package Subs::UVOTReport; ############################################################################## # # DESCRIPTION: This creates an HTML report of UVOT exposures. It is largely # DESCRIPTION: a translation of the FITS exposure report data. # # HISTORY: # HISTORY: $Log: UVOTReport.pm,v $ # HISTORY: Revision 1.27 2006/04/27 15:47:20 apsop # HISTORY: Allow for either INDEF or NULL values returned from FITSfile class. # HISTORY: # HISTORY: Revision 1.26 2006/04/14 18:26:35 apsop # HISTORY: Fix bug in calculating intensifier exposure. # HISTORY: # HISTORY: Revision 1.25 2006/01/11 21:05:52 apsop # HISTORY: Calculate exp times for blocked filter. # HISTORY: # HISTORY: Revision 1.24 2005/11/18 17:58:16 apsop # HISTORY: Check for undefined values in @mode and @bin_level. # HISTORY: # HISTORY: Revision 1.23 2005/11/08 19:54:35 apsop # HISTORY: <Previous comment bogus> Test for undefined mode value. # HISTORY: # HISTORY: Revision 1.22 2005/11/08 19:22:28 apsop # HISTORY: Populate the TIMELIST and DATALIST hashes. Used to be an SWCheckInput. # HISTORY: # HISTORY: Revision 1.21 2005/09/30 17:04:17 apsop # HISTORY: More tests for INDEF fields in the uvot cat file. # HISTORY: # HISTORY: Revision 1.20 2005/09/30 12:18:02 apsop # HISTORY: Bug fix. # HISTORY: # HISTORY: Revision 1.19 2005/09/28 17:30:42 apsop # HISTORY: More tests to deal with INDEF values. # HISTORY: # HISTORY: Revision 1.18 2005/09/27 17:44:03 apsop # HISTORY: Put in several checks to deal with INDEF values. # HISTORY: # HISTORY: Revision 1.17 2005/09/19 13:35:31 apsop # HISTORY: Only count on-target time when calculating exposure for cleaned event lists. # HISTORY: # HISTORY: Revision 1.16 2005/08/31 19:04:14 apsop # HISTORY: Protect against null values. # HISTORY: # HISTORY: Revision 1.15 2005/08/30 14:11:06 apsop # HISTORY: Major rework. Replace loss column with image_loss. Use calculated frame time. New exposure calculation. # HISTORY: # HISTORY: Revision 1.14 2005/03/07 22:43:56 apsop # HISTORY: Changes to deal with UNDEF values in the input fits files. # HISTORY: # HISTORY: Revision 1.13 2004/09/05 19:06:21 apsop # HISTORY: Make sure that exposure param values always get initialize to zero. # HISTORY: # HISTORY: Revision 1.12 2004/08/15 18:41:52 apsop # HISTORY: Fix problem with info being available only in certain modes # HISTORY: # HISTORY: Revision 1.11 2004/08/13 14:27:06 apsop # HISTORY: Update Report modules to record exposure information in job.par file. # HISTORY: # HISTORY: Revision 1.10 2004/05/06 20:02:34 dah # HISTORY: Add version number back into the header comments. # HISTORY: # HISTORY: Revision 1.9 2004/04/16 20:21:18 dah # HISTORY: Begin using embedded history records # HISTORY: # # VERSION: 0.0 # # ############################################################################## use Subs::Sub; use Subs::HTMLPage; use Subs::UvotNames; @ISA = ("Subs::HTMLPage"); use strict; sub new { my $proto=shift; my $file=$proto->filename()->get("report", "uvot"); my $seq = $proto->jobpar()->read('sequence') .".". $proto->jobpar()->read('seqprocnum'); my $self=$proto->SUPER::new($file, "UVOT Exposure Report for $seq"); $self->{DESCRIPTION}="Making UVOT HTML Exposure Report"; return $self; } ################## # METHODS: ################## ############################################################################## # ############################################################################## sub body { my $self=shift; my $log =$self->log(); my $filename=$self->filename(); my $procpar =$self->procpar(); my $jobpar =$self->jobpar(); my $exps; for(my $ifilt=0; $ifilt < @$Subs::UvotNames::filterCodes; $ifilt++){ for(my $imode=0; $imode < @$Subs::UvotNames::modeNames; $imode++){ $$exps[$ifilt][$imode] = 0; } } ####################################### # get the exposure report file ####################################### my $file = $filename->get("hk", "u", "ct", "*"); if ( ! -f $file ) { $log->entry("No UVOT exposure report FITS file"); }else{ ######################################## # read the FITS file ######################################## my $fits = Util::FITSfile->new($file,1); my @expid = $fits->cols("EXPID")->table(); my @time = $fits->cols("TIME")->table(); my @exp_des = $fits->cols("EXP_DES")->table(); my @mode = $fits->cols("MODEID")->table(); my @submode = $fits->cols("SUBMODE")->table(); my @filter = $fits->cols("FILTER")->table(); my @im_x0 = $fits->cols("IM_X0_ACT")->table(); my @im_x1 = $fits->cols("IM_X1_ACT")->table(); my @im_y0 = $fits->cols("IM_Y0_ACT")->table(); my @im_y1 = $fits->cols("IM_Y1_ACT")->table(); my @ev_x0 = $fits->cols("EV_X0_ACT")->table(); my @ev_x1 = $fits->cols("EV_X1_ACT")->table(); my @ev_y0 = $fits->cols("EV_Y0_ACT")->table(); my @ev_y1 = $fits->cols("EV_Y1_ACT")->table(); my @bin_level = $fits->cols("BINLVL")->table(); my @nevents = $fits->cols("NEVENTS")->table(); my @gevents = $fits->cols("GEVENTS")->table(); my @gimage = $fits->cols("GIMAGE")->table(); my @nframes = $fits->cols("NFRAMES")->table(); my @frame_duration = $fits->cols("FrameTime")->table(); my @reason = $fits->cols("REASON")->table(); my @ifiles = $fits->cols("IFILEREF")->table(); my @imename = $fits->cols("IMENAME")->table(); ######################### # write the HTML table ######################### $self->begin_table("Exp ID", "ICU Label", "Mode", "Submode", "Filter", "Event Window", "Image Window", "Binning", "Duration", "Count Rate", "Image Data Loss", "Completion"); my $nrows = $fits->nrows(); for(my $i=0; $i<$nrows; $i++) { my $exp_des = 0; $exp_des = "0x".sprintf("%x", $exp_des[$i]) if $exp_des[$i]; my $submode = 0; $submode = "0x".sprintf("%x", $submode[$i]) if ($submode[$i] && $submode[$i] !~ /(INDEF|NULL)/ ); my ($event_window_x, $event_window_y, $image_window_x, $image_window_y) = ('n/a', 'n/a', 'n/a', 'n/a'); if(defined($mode[$i]) && $mode[$i] !~ /(INDEF|NULL)/){ if($mode[$i]==2 || $mode[$i]==4){ if(defined($ev_x1[$i]) && $ev_x1[$i] !~ /(INDEF|NULL)/ && defined($ev_x0[$i]) && $ev_x0[$i] !~ /(INDEF|NULL)/ ){ $event_window_x = $ev_x1[$i] - $ev_x0[$i] + 1; }else{ $event_window_x = 'null'; } if(defined($ev_y1[$i]) && $ev_y1[$i] !~ /(INDEF|NULL)/ && defined($ev_y0[$i]) && $ev_y0[$i] !~ /(INDEF|NULL)/ ){ $event_window_y = $ev_y1[$i] - $ev_y0[$i] + 1; }else{ $event_window_y = 'null'; } } if($mode[$i]==3 || $mode[$i]==4){ if(defined($im_x1[$i]) && $im_x1[$i] !~ /(INDEF|NULL)/ && defined($im_x0[$i]) && $im_x0[$i] !~ /(INDEF|NULL)/){ $image_window_x = $im_x1[$i] - $im_x0[$i] + 1; }else{ $image_window_x = 'null'; } if(defined($im_y1[$i]) && $im_y1[$i] !~ /(INDEF|NULL)/ && defined($im_y0[$i]) && $im_y0[$i] !~ /(INDEF|NULL)/ ){ $image_window_y = $im_y1[$i] - $im_y0[$i] + 1; }else{ $image_window_y = 'null'; } } } my $count_rate = 'null'; my $exposure; if($nframes[$i] && $nframes[$i] !~ /(INDEF|NULL)/){ $exposure = $nframes[$i]*$frame_duration[$i]; $$exps[$filter[$i]][$mode[$i]] += $exposure; $count_rate = sprintf("%.1f", $nevents[$i]/$exposure) if $exposure; } my $gcounts = 0; if( defined($mode[$i]) && $mode[$i] !~ /(INDEF|NULL)/ ){ if($mode[$i]==2 || $mode[$i]==6){ $gcounts = $gevents[$i]; }else{ $gcounts = $gimage[$i]; } } my $loss = 0; if( $ifiles[$i] ne 'NONE' ){ ####################################################### # Determine the percentage of NULL pixels in the image ####################################################### my $stats=Util::HEAdas->new("ftstat") ->params({infile => $ifiles[$i] .'['. $imename[$i] .']', centroid => 'no'}) ->verbose(0) ->run(); my $parfile = $stats->parfile(); my $nulls = $parfile->read('null'); if( $nulls ){ $loss = $parfile->read('good') / $nulls; $loss = 1/(1+$loss); } } my $filter_name = $$Subs::UvotNames::filterNames[$filter[$i]]; my $reason_name = 'UNKNOWN'; $reason_name = $$Subs::UvotNames::reasonNames[$reason[$i]] if($reason[$i] && $reason[$i] !~ /(INDEF|NULL)/); my $mode_name = 'UNKNOWN'; $mode_name = $$Subs::UvotNames::modeNames[$mode[$i]] if($mode[$i] && $mode[$i] !~ /(INDEF|NULL)/); $self->table_row($expid[$i], $exp_des, $mode_name ? $mode_name : 'Unknown', $submode, $filter_name ? $filter_name : 'Unknown', "$event_window_x x $event_window_y", "$image_window_x x $image_window_y", $bin_level[$i] ? $bin_level[$i] : 'Unknown', $exposure ? sprintf("%.1f s",$exposure) : 'null', "$count_rate/s", sprintf("%.1f%%",$loss), $reason_name ? $reason_name : 'Unknown' ); } $self->end_table(); } $self->event_exposures(); for(my $ifilt=0; $ifilt<=10; $ifilt++){ my $parm = $$Subs::UvotNames::filterParams{ $$Subs::UvotNames::filterCodes[$ifilt] }; my $sumexp = $$exps[$ifilt][3] + $$exps[$ifilt][7] + $$exps[$ifilt][9] + $$exps[$ifilt][10]; $jobpar->set({ 'uvot_image_'.$parm => sprintf('%.03f', $sumexp) }); $sumexp = $$exps[$ifilt][2] + $$exps[$ifilt][4] + $$exps[$ifilt][6]; $jobpar->set({ 'uvot_unf_'.$parm => sprintf('%.03f', $sumexp) }); } } # end of body method sub event_exposures { my $self=shift; my $log =$self->log(); my $filename=$self->filename(); my $procpar =$self->procpar(); my $jobpar =$self->jobpar(); my $gtisum=Util::Stool->new("compute_exposure") ->verbose(0); my $tmpgti = 'otgti.tmp'; unlink $tmpgti; $gtisum->command_line("$tmpgti\[STDGTI\]"); my $ontarget = $filename->get('gti', 's', 'ot', 0); my $merge = Util::Ftool->new('mgtime') ->params({merge => 'AND', outgti => $tmpgti}); foreach my $filter (keys %$Subs::UvotNames::filterParams){ my $exposure = 0; my @efiles = $filename->get('event', 'uvot', "$filter*", '*'); @efiles = $filename->get('unfiltered', 'uvot', "$filter*", '*') unless @efiles; foreach my $rawFile (@efiles) { my $rawFits = Util::FITSfile->new($rawFile); my $nhdus = $rawFits->nhdus(); for(my $hdu=2; $hdu<$nhdus; $hdu++){ $rawFits->ext($hdu); my $name = $rawFits->keyword('EXTNAME'); if($name =~ /^GTI/){ $merge->params({ingtis => "$ontarget $rawFile\[$name\]"}) ->run(); $exposure += $gtisum->run()->stdout(); unlink $tmpgti; } } } $jobpar->set({'uvot_evt_' . $$Subs::UvotNames::filterParams{$filter} => sprintf('%.03f', $exposure)}); } }