[fitswcs] Polarization codes

Mark Calabretta mcalabre at atnf.CSIRO.AU
Mon Mar 17 00:58:11 EDT 2008


On Fri 2008/03/14 02:39:27 -0000, Paddy Leahy wrote
in a message to: Mark Calabretta <mcalabre at atnf.csiro.au>
and copied to: fitswcs at nrao.edu

Dear Paddy,

>> (I'm not sure what you have in mind for "undefined").
>
>Intended for archives which write a standard list of header keywords, but 
>may contain data for which the polarization is not known, too messy to
>specify (eg. response varies substantially over the FOV) or not defined
>(eg. polarization-independent beams, maps of UHECR arrival directions).

OK, but why not simply omit the polarization axis?

>> I agree with the first part (which is the same as your first point), but
>> not with the comment about position angle since that is the measurement,
>> e.g. how would you combine it with brightness, spectral index, or
>> anything else?
>
>Example: From (IQUV) absorption spectra, calculate the optical depth 
>separately for polarized and unpolarized emission. The ratio (fractional 
>polarization of optical depth) tells you something interesting about the 
>absorbing material. The polarized absorption may also be anisotropic, 
>hence there may be an angle for the polarized optical depth. This can 
>happen in theory for absorption by Zeeman-split lines, although I have to 
>admit that I've not heard about a measurement in an astronomical context.

We're probably talking at cross-purposes, my objection is much simpler;
if the STOKES type indicates "polarization angle" then the measurement
must be of polarization angle, not say, brightness temperature.  In
contrast, if the STOKES type indicates Stokes-I, then the measurement
could be brightness temperature, optical depth, spectral index, or
whatever.

>Building on your point that really we are dealing with vector-valued 
>quantities, right now the STOKES "axis" in practice just specifies 3 ways 
>of building such a vector (XX,..) (RR...) (I...), i.e. 3 coordinate 
>systems in the same space.

Three full polarization measurements plus the several meaningful one-,
and two-element measurements.  "Meaningful" here precludes odd
combinations such as (XX,XY,YX) - these are not representable, but
since they're not meaningful it doesn't matter.

>dataset 1:
>NAXIS3  = 4
>...
>CTYPE3  = 'STOKES'
>CRPIX3  = 11
>POLCO1  =  'I'    / Implied unit is BUNIT
>POLCO2  =  'Q/I'  / Dimensionless ratio
>POLCO3  =  'U/I'  / Dimensionless ratio 
>POLCO4  =  'V/I'  / Dimensionless ratio

I think we have the square peg going into the round hole.  Just a few
more gentle taps should do it!

>dataset 2:
>NAXIS3  = 3
>...
>CTYPE3  = 'STOKES'
>CRPIX3  = 11
>POLCO1  = 'LinPolInt' / [BUNIT] Linearly polarized intensity
>POLCO2  = 'PolAng'    / [deg] Polarization angle in degrees
>POLCO3  = 'I'         / [BUNIT] Total intensity

Let's focus on this example since it stretches the current conventions.

1) The first problem is the inconsistent use of BUNIT, in fact it
   violates the standard.  If units are to be implied for one (POLCO2)
   then they may as well be implied for all.
   
   The obvious solution is simply to omit BUNIT.  Alternatively, BUNIT
   might be given a special value such as 'Mixed'.

2) However, implied units are unsatisfactory.  Past experience has shown
   that FITS writers will use whatever units they want.
   
   No problem, simply define BUNITi - that is an extension, not a
   violation of the standard.

3) What's in a name?  The choice of POLCOi was arbitrary.  Instead,
   let's choose a name less specific to polarization, after all, this
   mechanism is potentially useful for other types of measurement.  I'm
   thinking of colour for one, but what about vector fields such as E or
   B?
   
   We have BUNITi so the obvious choice is BTYPEi.

4) CRPIX3 = 11 or similar was forced because of the old baggage
   associated with the 'STOKES' axis type.  CRPIX = 11 is really just a
   magic value that says "look for POLCOi (i.e. BYTPEia/BUNITia)".  It
   was forced because the default value of CRPIX is 0, but as a STOKES
   value that has been assigned another meaning ("BEAM" in AIPS).  We're
   faced with a horrible kludge behaving badly!  Ideally we don't want
   to have to associate CRPIXia, CDELTia, CRVALia, or PCi_ja with these
   special axis types at all.  

   The answer is simply to side-step the problem by changing the axis
   name to 'Polarization' thereby giving us a clean slate.  In any case
   the name 'STOKES' dates from a time when it was only used to record
   I,Q,U,V; RR,LL,RL,LR were added later, and XX,YY,XY,YX later still
   (IIRC).  'STOKES' is a misnomer for these latecomers.

   Changing CTYPE to 'Polarization' also has an additional benefit for
   old FITS readers (see below).

5) Now sprinkle some syntactic sugar.  Since CTYPEia takes an alternate
   version code (the "a"), that forces BTYPEi and BUNITi to take
   alternate codes as well.
   
   Hence we must generalise: BTYPEia and BUNITia.

With above changes your header fragment becomes

NAXIS3  = 3
...
CTYPE3X = 'Polarization'
BTYPE1X = 'LinPolInt'
BUNIT1X = 'K'
BTYPE2X = 'PolAng'
BUNIT2X = 'deg'
BTYPE3X = 'I'
BUNIT3X = 'K'

where I've used 'X' simply to demonstrate an alternate code.  However,
there's more.

The flaw in this scheme is that in its implemention it must be known
a priori that CTYPE = 'Polarization' is interpreted in a special way -
there is nothing in the header that says so directly.  This is bad,
knowledge of all such keywords would have to be built into software,
so we need new syntax to indicate the special usage.  There are several
possibilities,

  a) encode it in the CTYPE value itself as is done for celestial
     projections (e.g. 'RA---TAN'), or

  b) introduce a new keyword, or

  c) define a special value of BUNIT, e.g. BUNIT = 'Mixed', which
     serves double-duty.

The advantage of (a) is that the information is self-contained in a
single keyrecord, with (b) you need to associate CTYPE with another
keyword which is a bit more work (ok not such a big deal).  Option (c)
requires an extension to the current definition of BUNIT.  Also, making
things do double-duty often bites you in the end.

Hence I favour (a).  Since what we have here is an ersatz method of
encoding vector measurement, I would suggest changing 'Polarization'
to 'VECTOR-Polarization', 'VECTOR-' here being the operative syntax.
Here is how it would work for colour representation:

NAXIS3  = 3
...
CTYPE3C = 'VECTOR-sRGB'
BTYPE1C = 'Red'
BUNIT1C = '%'
BTYPE2C = 'Green'
BUNIT2C = '%'
BTYPE3C = 'Blue'
BUNIT3C = '%'

Probably we should also allow this to be written as

NAXIS3  = 3
BUNIT   = '%'
...
CTYPE3C = 'VECTOR-sRGB'
BTYPE1C = 'sRed'
BTYPE2C = 'sGreen'
BTYPE3C = 'sBlue'

Note that the syntax is sufficient for a FITS reader to parse a CTYPE of
'VECTOR-sRGB' even if it doesn't know what 'VECTOR-sRGB' is.

Obviously there can only be one 'VECTOR-' axis per image, but you can
cram as much into that axis as you like.  E.g. a complex-valued vector
could have BTYPEia of 'A-real', 'A-imag', 'B-real', etc.

So far, these changes are essentially forced by the current standard, by
established usage, and (maybe!) by good practice.  The only degree of
freedom is in the names chosen for the keywords and keyvalues, and the
'VECTOR-' syntax.  Now I'd like to add a little more.

6) Your example of representing (PolAng,FracLinPol,I) as HSV is
   reminiscent of some musings on colour representation in FITS that
   I posted to this list a few years ago.  One of the ideas therein,
   originally suggested by Steve Allen, was to preserve the data values
   by providing rescaling keywords to get the colour components.

   Originally I thought this could be implemented via PVi_ma parameters,
   but the new machinery here suggests something more apposite: BZEROia
   and BSCALia (note the 'E' is dropped from BSCALE to allow more space
   for the 'ia' in case i > 9).

7) For completeness, the last thing would be to add BTYPE.
   
As an example, we might have a dual description:

NAXIS3  = 3
...
CTYPE3X = 'VECTOR-Polarization'
BTYPE1X = 'I'
BUNIT1X = 'K'
BTYPE2X = 'FracLinPol'
BUNIT2X = '%'
BTYPE3X = 'PolAng'
BUNIT3X = 'deg'

CTYPE3C = 'VECTOR-HSV'
BTYPE1C = 'Value'
BUNIT1C = '%'
BZERO1C = ...
BSCAL1C = ...
BTYPE2C = 'Saturation'
BUNIT2C = '%'
BZERO2C = ...
BSCAL2C = ...
BTYPE3C = 'Hue'
BUNIT3C = '%'
BZERO3C = ...
BSCAL3C = ...

where the zero values and scales are floating point numbers chosen
appropriately to scale the polarization components to colour components
in the proper range.  Note how the HSV order has been permuted as
(Value,Saturation,Hue) to match (I,FracLinPol,PolAng).

Now we must consider what will happen when old FITS readers encounter
these new keywords.  Firstly we must recognize that there is no chance
that any software that has not been updated will be able to deduce the
correct meaning for new usage, no matter how it is implemented.

Of those in the example above, the only keywords that old readers will
"see" are

NAXIS3  = 3
CTYPE3X = 'VECTOR-Polarization'
CTYPE3C = 'VECTOR-HSV'

How will they interpret these?  If conformant to the WCS standards, then
they will provide default values for CRPIXia, CDELTia, and CRVALia and
will compute coordinate values equal to the pixel coordinate value.
This is meaningless but harmless.  Output labelled with types of
'VECTOR-Polarization' (n.b. not 'STOKES') and 'VECTOR-HSV' should alert
any human interpreters that something is wrong.

>Obviously this is byzantine compared to my original proposal. Depends how 

Byzantine?  Just imagine how it would look in XML!  Anyway, with just
a few new keywords we now have a workable, if not ideal, framework for
storing any vector-valued image.

Regards, Mark





More information about the fitswcs mailing list