our
$VERSION
=
'1.66'
;
my
%UNIT_MAP
=
(
AIRMASS_START
=>
'AMSTART'
,
AZIMUTH_START
=>
'AZSTART'
,
ELEVATION_START
=>
'ELSTART'
,
FILENAME
=>
'FILE_ID'
,
DR_RECIPE
=>
"RECIPE"
,
HUMIDITY
=>
'HUMSTART'
,
LATITUDE
=>
'LAT-OBS'
,
LONGITUDE
=>
'LONG-OBS'
,
OBJECT
=>
'OBJECT'
,
OBSERVATION_NUMBER
=>
'OBSNUM'
,
PROJECT
=>
'PROJECT'
,
SCAN_PATTERN
=>
'SCAN_PAT'
,
STANDARD
=>
'STANDARD'
,
TAI_UTC_CORRECTION
=>
'DTAI'
,
UT1_UTC_CORRECTION
=>
'DUT1'
,
WIND_BLIND
=>
'WND_BLND'
,
X_APERTURE
=>
'INSTAP_X'
,
Y_APERTURE
=>
'INSTAP_Y'
,
);
my
%CONST_MAP
= ();
__PACKAGE__->_generate_lookup_methods( \
%CONST_MAP
, \
%UNIT_MAP
);
our
$COORDS
;
sub
translate_from_FITS {
my
$class
=
shift
;
my
$headers
=
shift
;
$COORDS
=
undef
;
return
$class
->SUPER::translate_from_FITS(
$headers
,
@_
);
}
sub
to_UTDATE {
my
$class
=
shift
;
my
$FITS_headers
=
shift
;
$class
->_fix_dates(
$FITS_headers
);
return
$class
->SUPER::to_UTDATE(
$FITS_headers
,
@_
);
}
sub
to_UTEND {
my
$class
=
shift
;
my
$FITS_headers
=
shift
;
$class
->_fix_dates(
$FITS_headers
);
return
$class
->SUPER::to_UTEND(
$FITS_headers
,
@_
);
}
sub
to_UTSTART {
my
$class
=
shift
;
my
$FITS_headers
=
shift
;
$class
->_fix_dates(
$FITS_headers
);
return
$class
->SUPER::to_UTSTART(
$FITS_headers
,
@_
);
}
sub
to_RA_BASE {
my
$self
=
shift
;
my
$FITS_headers
=
shift
;
my
$coords
=
$self
->_calc_coords(
$FITS_headers
);
return
undef
unless
defined
$coords
;
return
$coords
->ra(
format
=>
'deg'
);
}
sub
to_DEC_BASE {
my
$self
=
shift
;
my
$FITS_headers
=
shift
;
my
$coords
=
$self
->_calc_coords(
$FITS_headers
);
return
undef
unless
defined
$coords
;
return
$coords
->dec(
format
=>
'deg'
);
}
sub
to_TAU {
my
$self
=
shift
;
my
$FITS_headers
=
shift
;
my
$tau
=
undef
;
for
my
$src
(
qw/ TAU225 WVMTAU /
) {
my
$st
=
$src
.
"ST"
;
my
$en
=
$src
.
"EN"
;
my
@startvals
=
$self
->via_subheader_undef_check(
$FITS_headers
,
$st
);
my
@endvals
=
$self
->via_subheader_undef_check(
$FITS_headers
,
$en
);
my
$startval
=
$startvals
[0];
my
$endval
=
$endvals
[-1];
my
$have_start
= ((
defined
$startval
) and (
$startval
!= 0.0));
my
$have_end
= ((
defined
$endval
) and (
$endval
!= 0.0));
if
(
$have_start
and
$have_end
) {
$tau
= (
$startval
+
$endval
) / 2;
last
;
}
elsif
(
$have_start
) {
$tau
=
$startval
;
}
elsif
(
$have_end
) {
$tau
=
$endval
;
}
}
return
$tau
;
}
sub
to_SEEING {
my
$self
=
shift
;
my
$FITS_headers
=
shift
;
my
$seeing
= 0.0;
my
@startvals
=
$self
->via_subheader_undef_check(
$FITS_headers
,
"SEEINGST"
);
my
@endvals
=
$self
->via_subheader_undef_check(
$FITS_headers
,
"SEEINGEN"
);
my
$startval
=
$startvals
[0];
my
$endval
=
$endvals
[-1];
if
(
defined
$startval
&&
defined
$endval
) {
$seeing
= (
$startval
+
$endval
) / 2;
}
elsif
(
defined
$startval
) {
$seeing
=
$startval
;
}
elsif
(
defined
$endval
) {
$seeing
=
$endval
;
}
return
$seeing
;
}
sub
to_OBSERVATION_ID_SUBSYSTEM {
my
$self
=
shift
;
my
$FITS_headers
=
shift
;
my
@obsidss
;
for
my
$h
(
qw/ OBSIDSS OBSID_SUBSYSNR /
) {
my
@found
=
$self
->via_subheader(
$FITS_headers
,
$h
);
if
(
@found
) {
@obsidss
=
@found
;
last
;
}
}
my
@all
;
if
(
@obsidss
) {
my
%seen
;
@all
=
grep
{ !
$seen
{
$_
}++ }
@obsidss
;
}
return
\
@all
;
}
sub
to_SUBSYSTEM_IDKEY {
my
$self
=
shift
;
my
$FITS_headers
=
shift
;
for
my
$try
(
qw/ OBSIDSS OBSID_SUBSYSNR /
) {
my
@results
=
$self
->via_subheader(
$FITS_headers
,
$try
);
return
$try
if
@results
;
}
return
;
}
sub
to_DOME_OPEN {
my
$self
=
shift
;
my
$FITS_headers
=
shift
;
my
(
$n_open
,
$n_closed
,
$n_other
) = (0, 0, 0);
foreach
my
$header
(
qw/DOORSTST DOORSTEN ROOFSTST ROOFSTEN/
) {
foreach
my
$value
(
$self
->via_subheader(
$FITS_headers
,
$header
)) {
if
(
$value
=~ /^
open
$/i) {
$n_open
++;
}
elsif
(
$value
=~ /^closed$/i) {
$n_closed
++;
}
else
{
$n_other
++;
}
}
}
if
(
$n_open
and not (
$n_closed
or
$n_other
)) {
return
1;
}
if
(
$n_closed
and not (
$n_open
or
$n_other
)) {
return
0;
}
return
undef
;
}
sub
from_DOME_OPEN {
my
$self
=
shift
;
my
$generic_headers
=
shift
;
my
$value
=
undef
;
if
(
exists
$generic_headers
->{
'DOME_OPEN'
}) {
my
$dome
=
$generic_headers
->{
'DOME_OPEN'
};
if
(
defined
$dome
) {
$value
=
$dome
?
'Open'
:
'Closed'
;
}
}
return
map
{
$_
=>
$value
}
qw/DOORSTST DOORSTEN ROOFSTST ROOFSTEN/
;
}
sub
to_REMOTE {
my
$self
=
shift
;
my
$FITS_headers
=
shift
;
my
$remote
;
if
(
exists
(
$FITS_headers
->{
'REMOTE'
})) {
$remote
=
$FITS_headers
->{
'REMOTE'
};
}
else
{
$remote
=
''
}
if
(
uc
(
$remote
) =~ /REMOTE/) {
$remote
= 1;
}
elsif
(
uc
(
$remote
) =~ /LOCAL/) {
$remote
= 0;
}
else
{
$remote
=
undef
;
}
return
$remote
;
}
sub
from_REMOTE {
my
$self
=
shift
;
my
$generic_headers
=
shift
;
my
$value
=
undef
;
if
(
exists
$generic_headers
->{
'REMOTE'
}) {
my
$remote
=
$generic_headers
->{
'REMOTE'
};
if
(
defined
$remote
) {
$value
=
$remote
?
'REMOTE'
:
'LOCAL'
;
}
}
return
(
OPER_LOC
=>
$value
);
}
sub
_calc_coords {
my
$self
=
shift
;
my
$FITS_headers
=
shift
;
$self
->_fix_dates(
$FITS_headers
);
if
(
defined
(
$COORDS
) &&
UNIVERSAL::isa(
$COORDS
,
"Astro::Coords"
) ) {
return
$COORDS
;
}
my
$telescope
=
$FITS_headers
->{
'TELESCOP'
};
my
(
$dateobs
,
$az
,
$el
);
my
@keys
= ( {
date
=>
"DATE-OBS"
,
az
=>
"AZSTART"
,
el
=>
"ELSTART"
},
{
date
=>
"DATE-END"
,
az
=>
"AZEND"
,
el
=>
"ELEND"
} );
for
my
$keys_to_try
(
@keys
) {
my
@dateobs
=
$self
->via_subheader(
$FITS_headers
,
$keys_to_try
->{date} );
my
@azref
=
$self
->via_subheader(
$FITS_headers
,
$keys_to_try
->{az} );
my
@elref
=
$self
->via_subheader(
$FITS_headers
,
$keys_to_try
->{el} );
my
$idx
;
(
$idx
,
$dateobs
) = _middle_value(\
@dateobs
,
$idx
);
(
$idx
,
$az
) = _middle_value(\
@azref
,
$idx
);
(
$idx
,
$el
) = _middle_value(\
@elref
,
$idx
);
last
if
(
defined
$dateobs
&&
defined
$az
&&
defined
$el
);
}
if
(
defined
$dateobs
&&
defined
$telescope
&&
defined
$az
&&
defined
$el
) {
my
$coords
= new Astro::Coords(
az
=>
$az
,
el
=>
$el
,
units
=>
'degrees'
,
);
$coords
->telescope( new Astro::Telescope(
$telescope
) );
my
$dt
= Astro::FITS::HdrTrans::Base->_parse_iso_date(
$dateobs
);
return
unless
defined
$dt
;
$coords
->datetime(
$dt
);
$COORDS
=
$coords
;
return
$COORDS
;
}
return
undef
;
}
sub
_middle_value {
my
$arr
=
shift
;
my
$idx
=
shift
;
$idx
=
int
((
scalar
@$arr
) / 2)
unless
defined
$idx
;
return
(
$idx
,
$arr
->[
$idx
])
if
(
defined
$arr
->[
$idx
]);
for
my
$idx
(0..
$#$arr
) {
my
$val
=
$arr
->[
$idx
];
return
(
$idx
,
$val
)
if
defined
$val
;
}
return
(
undef
,
undef
);
}
1;