Determine if location is inside Field of View
CIAO 4.15 Science Threads
Overview
Synopsis:
It may be necessary to determine if a celestial location (RA, Dec), is located within a Chandra observation. There are several ways to get an approximate answer by doing a radius search around the observation's nominal pointing RA_PNT,DEC_PNT. However, especially for ACIS observations, this can lead to many incorrect results since the number and configuration of CCDs varies between observations. There are also things such as subarrays and windows to consider which can further limit the field of view.
One of the standard Chandra data products is a Field of View (FOV) file -- a FITS region file that provides a polygon around each CCD.
Remember that due to dither, the square CCDs are "blurred" on the sky so the observed field of view must be described by a polygon.
This thread will show how to use the FOV files to determine if a celestial location, rather than a physical location, is located in a particular Chandra observation.
Purpose:
Related Links:
- skyfov tool ahelp file
- dmregions concept ahelp file
- Python region module help file
- Data Products Guide: FOV files
- ASC-FITS-REGION specification, Rots and McDowell.
- CXC Footprint Service
Last Update: 15 Feb 2022 - Review for CIAO 4.14. Updated for Python3, new pyregion module, and Repro-5+CALDB-4.9.6.
Contents
- Getting Started
- Check if celestial location is inside FOV
- Checking several FOV files
- Summary
- History
Getting Started
Download the sample data: 5794 (SDSS J1004+4112)
unix% download_chandra_obsid 5794 fov
acis_fov.fits
Check if celestial location is inside FOV
As with all Chandra FITS region files, the coordinates in the FOV file are stored in sky pixels, on the same tangent plane used by the event file for the observation. However, the POS (position) column also has a World Coordinate System (WCS) to convert the X,Y values to RA,Dec. This can be seen when the file is dmlist'd with the cols options:
unix% dmlist acis_fov.fits cols -------------------------------------------------------------------------------- Columns for Table Block FOV -------------------------------------------------------------------------------- ColNo Name Unit Type Range 1 POS(X,Y)[13] pixel Real8(13) -Inf:+Inf Position 2 SHAPE String[16] Region shape type 3 R[2] pixel Real8(2) -Inf:+Inf Radius 4 ROTANG[2] pixel Real8(2) -Inf:+Inf Angle 5 COMPONENT Int2 - Component number 6 CCD_ID Int2 - CCD ID -------------------------------------------------------------------------------- World Coord Transforms for Columns in Table Block FOV -------------------------------------------------------------------------------- ColNo Name 1: EQPOS(RA ) = (+151.1396)[degree] +TAN[(-0.000136667)* (POS(X)-(+4096.50))] (DEC) (+41.2327 ) (+0.000136667) ( (Y) (+4096.50))
By default when CIAO tools and applications try to use the FOV files they will use the POS position values, which are simply sky X and Y values. For example using the CIAO Python region module
unix% python >>> from region import * >>> myreg = CXCRegion("acis_fov.fits") >>> print(myreg) polygon(3467.6263224,3369.28090836,3467.6565089,3369.17640877,3467.71661574, 3369.00061749,3467.83371847,3368.86039342,3467.8694516,3368.83401957, 3467.91668997,3368.81529982,3468.48358382,3368.69476487,3468.70314573, 3368.65086168,3493.34049452,3364.67234601,4473.49875929,3207.66038239, 4498.14437164,3203.73342053,4501.24422987,3203.25600105,4504.06889614, 3202.85557739,4504.23454267,3202.84091307,4504.32267389,3202.83736965, 4504.42159188,3202.83358699,4504.86841334,3202.83134235,4505.00642326, 3202.83089484,4505.0625378,3202.84329322,4505.32268684,3203.2149399, 4506.65550781,3210.61828139,4510.97796182,3235.10243102,4671.97193121, 4241.3238962,4672.00675252,4241.91272155,4671.92356958,4242.71362919, 4671.90199236,4242.80272213,4671.76416795,4243.26341158,4671.74936787, 4243.29409085,4671.59095838,4243.44934783,4670.88311161,4243.97157507, 4670.80892245,4244.01169209,4670.04187616,4244.33543306,4669.45877326, 4244.484041,4668.25805682,4244.76331822,4667.93228389,4244.82547885, 3662.77667455,4405.60051292,3646.01017685,4408.17768906,3635.19102762, 4409.56424316,3634.88682614,4409.58532979,3634.60679034,4409.59359905, 3634.51043422,4409.56149899,3634.48214285,4409.54244325,3634.35678717, 4409.45324929,3633.86037361,4407.37390775,3633.07781324,4403.63323961, 3633.05827282,4403.51162292,3471.95423823,3396.71335899,3467.6263224, 3369.28090836)
This shows the POLYGON shape and the typical ACIS sky position values (in the 3000-5000 range). However, this is not directly useful when a celestial location, RA,Dec in decimal degrees, needs to be checked.
Using the CXC Datamodel virtual file syntax, it is possible to change the above example to use the WCS values in the virtual EQPOS column. By using a [cols ] filter, the virtual EQPOS column will be used instead of the sky positions as shown below
>>> mycelreg = CXCRegion("acis_fov.fits[cols eqpos,shape,component]") >>> print(mycelreg) polygon(151.258014222,41.1313973997,151.25800872,41.1313831235,151.257997772, 41.1313591096,151.257976491,41.1313399667,151.257970001,41.1313363687, 151.257961425,41.1313338188,151.257858536,41.1313174472,151.257818686, 41.1313114864,151.253347423,41.1307720755,151.075524743,41.1093454231, 151.071054978,41.1088060117,151.070492786,41.1087404092,151.069980498, 41.1086853585,151.069950455,41.1086833352,151.06993447,41.1086828407, 151.069916528,41.1086823123,151.069835482,41.1086819536,151.06981045, 41.1086818765,151.06980027,41.1086835644,151.069753025,41.1087343256, 151.069510124,41.1097459549,151.068722246,41.1130915976,151.039298954, 41.250585464,151.039292495,41.2506659309,151.039307441,41.2507754018, 151.039311344,41.2507875813,151.039336296,41.2508505648,151.03933898, 41.25085476,151.039367742,41.2508760045,151.039496299,41.2509474918, 151.039509776,41.2509529866,151.039649138,41.250997357,151.039755101, 41.2510177622,151.039973305,41.2510561265,151.04003251,41.251064675, 151.222775437,41.2730570221,151.225824701,41.2734071147,151.227792311, 41.2735951989,151.227847631,41.2735980405,151.227898555,41.2735991337, 151.22791607,41.2735947339,151.227921212,41.2735921259,151.227943991, 41.2735799195,151.228033894,41.2732956776,151.228175536,41.2727843501, 151.228179067,41.2727677266,151.257235426,41.1351472552,151.258014222, 41.1313973997)
The additional columns, shape and component are needed to complete the FITS region definition. The polygon points are now the sky X,Y values converted to RA,Dec.
The regInsideRegion routine can then be used to check whether a celestial location is within the field-of-view. Below the nominal pointing is checked along with a location several degrees away.
>>> !dmlist acis_fov.fits header,clean | grep PNT RA_PNT 151.1439070093 [deg] Pointing RA DEC_PNT 41.2308402045 [deg] Pointing Dec ROLL_PNT 99.0663114612 [deg] Pointing Roll >>> pointing=mycelreg.is_inside(151.1395864022, 41.2326566497 ) >>> random=mycelreg.is_inside(145.2, 45.0 ) >>> print(f"Is _PNT inside FOV? {pointing}") Is _PNT inside FOV? True >>> print(f"Is random location inside FOV? {random}") Is random location inside FOV? False
Checking several FOV files
This technique has been scripted into the FOVFiles Python class. After users have downloaded a set of FOV files, they can use this routine to determine which observations, from those they have downloaded, contains data for the requested location. This is essentially a local footprint service. An example is shown here:
unix% find_chandra_obsid "SDSS J1004+4112" # obsid sepn inst grat time obsdate piname target 5794 0.2 ACIS-S NONE 80.1 2005-01-01 Inada "SDSS J1004+4112" 11546 0.1 ACIS-S NONE 6.0 2010-03-08 Kochanek SDSS1004+4112 11547 0.1 ACIS-S NONE 6.0 2010-06-19 Kochanek SDSS1004+4112 11548 0.1 ACIS-S NONE 6.0 2010-09-23 Kochanek SDSS1004+4112 11549 0.1 ACIS-S NONE 6.0 2011-01-30 Kochanek SDSS1004+4112 14495 0.1 ACIS-S NONE 24.7 2013-01-27 Kochanek SDSS1004+4112 14496 0.1 ACIS-S NONE 24.7 2013-03-01 Kochanek SDSS1004+4112 14497 0.1 ACIS-S NONE 24.1 2013-10-05 Kochanek SDSS1004+4112 14498 0.1 ACIS-S NONE 23.8 2013-11-16 Kochanek SDSS1004+4112 14499 0.1 ACIS-S NONE 23.3 2014-04-29 Kochanek SDSS1004+4112 14500 0.1 ACIS-S NONE 24.7 2014-06-02 Kochanek SDSS1004+4112 19632 0.1 ACIS-S NONE 40.1 2017-01-23 Chartas SDSS1004+4112 19633 0.1 ACIS-S NONE 39.5 2017-04-16 Chartas SDSS1004+4112 19634 0.1 ACIS-S NONE 35.9 2017-06-27 Chartas SDSS1004+4112 19635 0.1 ACIS-S NONE 38.4 2017-10-01 Chartas SDSS1004+4112 19636 0.1 ACIS-S NONE 36.0 2018-01-17 Chartas SDSS1004+4112 19637 0.1 ACIS-S NONE 39.5 2018-04-19 Chartas SDSS1004+4112 unix% mkdir SDSS1004+4112 unix% cd SDSS1004+4112 unix% download_chandra_obsid 5794,11546,11547,11548,11549,14495,14496 fov unix% mv */primary/*fov1.fits.gz . unix% python >>> from ciao_contrib.region.check_fov import FOVFiles >>> regions = FOVFiles("*fov1.fits.gz") >>> print(regions) List of FOV files acisf11547_000N002_fov1.fits.gz acisf05794_000N003_fov1.fits.gz acisf11549_000N002_fov1.fits.gz acisf14496_000N001_fov1.fits.gz acisf11546_000N002_fov1.fits.gz acisf11548_000N002_fov1.fits.gz acisf14495_000N001_fov1.fits.gz >>> regions.inside( 151.25426, 41.090654) ['acisf11549_000N002_fov1.fits.gz', 'acisf11548_000N002_fov1.fits.gz', 'acisf14495_000N001_fov1.fits.gz']
In this example all the observations that include SDSS J1004+4112 are located using the find_chandra_obsid script and the FOV files are retrieved. Since the FOV files are small (only a few kBytes per file), they can be retrieved and used quickly before deciding which full datasets need to be downloaded. The FOVFiles object is then used to load all the files that were retrieved and to check the coverage of a location. In this example only 3 out of the 8 observations imaged the location.
Summary
This thread has shown how to use DM virtual file syntax to access the World Coordinate System attached to the sky position column in a Field of View file. This allows the user to easily check if arbitrary celestial coordinate are included in an observation.
The Chandra FOV files are not the tightest possible bounding polygon around the data. It may be slightly bigger (never smaller) than the actual footprint of the date due to dither, bad detector pixels, and based on the roll angle of the spacecraft. The gap is no more than half the dither pattern (based on roll).
This technique is used by the CXC Footprint service. The Level 1 FOV files are converted to celestial coordinates and stored in a database which is queried to determine which observations observed the input position.
History
31 Mar 2014 | Initial version. |
16 Jul 2014 | Added section showing how to use new FOVFiles routines to automate for multiple FOV files. |
23 Dec 2014 | Reviewed for CIAO 4.7; no changes. |
15 Feb 2022 | Review for CIAO 4.14. Updated for Python3, new pyregion module, and Repro-5+CALDB-4.9.6. |