#! /bin/sh # This is the LHEA perl script: /cvmfs/extras-fp7.egi.eu/extras/heasoft/ftools/x86_64-unknown-linux-gnu-libc2.19-0/bin/pcadeadspect2 # The purpose of this special block is to make this script work with # the user's local perl, regardless of where that perl is installed. # The variable LHEAPERL is set by the initialization script to # point to the local perl installation. #------------------------------------------------------------------------------- eval ' if [ "x$LHEAPERL" = x ]; then echo "Please run standard LHEA initialization before attempting to run /cvmfs/extras-fp7.egi.eu/extras/heasoft/ftools/x86_64-unknown-linux-gnu-libc2.19-0/bin/pcadeadspect2." exit 3 elif [ "$LHEAPERL" = noperl ]; then echo "During LHEA initialization, no acceptable version of Perl was found." echo "Cannot execute script /cvmfs/extras-fp7.egi.eu/extras/heasoft/ftools/x86_64-unknown-linux-gnu-libc2.19-0/bin/pcadeadspect2." exit 3 elif [ `$LHEAPERL -v < /dev/null 2> /dev/null | grep -ic "perl"` -eq 0 ]; then echo "LHEAPERL variable does not point to a usable perl." exit 3 else # Force Perl into 32-bit mode (to match the binaries) if necessary: if [ "x$HD_BUILD_ARCH_32_BIT" = xyes ]; then if [ `$LHEAPERL -V 2> /dev/null | grep -ic "USE_64_BIT"` -ne 0 ]; then VERSIONER_PERL_PREFER_32_BIT=yes export VERSIONER_PERL_PREFER_32_BIT fi fi exec $LHEAPERL -x $0 ${1+"$@"} fi ' if(0); # Do not delete anything above this comment from an installed LHEA script! #------------------------------------------------------------------------------- #!/usr/bin/perl # # File: pcadeadspect2 # # Description: Apply PCA deadtime correction to Standard2 spectrum # # Author: C. B. Markwardt # # use Getopt::Std; getopts(':h'); if (defined $opt_h) { print <= 1); print "----------------------------------------\n" if ($chatter >= 2); if ($std2file =~ m/^infile$/i) { $std2file = "$infile"; } $clobstr = $clobber ? "YES" : "NO"; if ($deadcorrtype =~ m/^LIVE$/i) { $deadcorrtype = "LIVE"; print " Using LIVE-time correction\n" if ($chatter >= 5); } elsif ($deadcorrtype =~ m/^ON$/i) { $deadcorrtype = "ON"; print " Using ON-time correction\n" if ($chatter >= 5); } else { die "ERROR: $deadcorrtype must be either 'LIVE' or 'ON'" } # =================================================== if ($outfile =~ m/^INFILE$/i) { $outfile = "$phafile"; } else { # Create new output file by copying input file &headas_clobberfile($outfile); $cmd = "ftcopy infile='$phafile' outfile='$outfile' clobber='$clobstr'"; print "COMMAND: $cmd\n" if ($chatter >= 5); system($cmd); if ($? || ! -f "$outfile") { die "ERROR: could not create '$outfile'"; } # Add output file to the scratch list... UNTIL the end of this # procedure where it is removed from the list. # IMPORTANT NOTE: this procedure expects "$outfile" to be the # first element of the @scratchfile list. push @scratchfiles, "$outfile"; } $outroot = "$outfile"; # ".expo" with extenpha parameter $outexpo = "$outroot".".expo"; $accumulate = "ONE"; # Accumulate a single live-time vector if ($deadcorrtype eq "LIVE") { $columns = "LiveTimeVect"; } else { $columns = "OnTimeVect"; } print " Accumulating columns $columns\n" if ($chatter >= 5); $cmd = "saextrct ". "infile='$infile' ". "printmode='SPECTRUM' spmode='SUM' ". "outroot='$outroot' extenpha='.expo' ". "accumulate='$accumulate' columns='$columns' ". "gtiorfile='$gtiorfile' gtiandfile='$gtiandfile' ". "timemin='$timemin' timemax='$timemax' timeint='$timeint' ". "clobber='$clobstr' ". "lcbinarray='$lcbinarray' gtiarray='$gtiarray' maxmiss='$maxmiss' ". "multiple='no' binsz=INDEF mfracexp='$mfracexp' ". "tnull=0.0 timezero=INDEF ". "mlcinten=INDEF mspinten=INDEF writesum='-' writemean='-' ". "gticols='$gticols' timecol='$timecol' extenlc='.lc' lcmode='SUM' ". "chmin=INDEF chmax=INDEF chint=INDEF chbin=INDEF ". "phasefile='-' ephem=INDEF period=INDEF phaseint=INDEF ". "obsdate='MJDREF' obstime='TSTART TSTOP' sensecase='no' ". "chkit='no' negative='IGNORE' dryrun='no' bailout='no'"; print "COMMAND: $cmd\n" if ($chatter >= 5); unlink("$outexpo"); @results = `$cmd`; if ($? || ! -f "$outexpo") { die "ERROR: could not create exposure file '$outexpo'"; } push @scratchfiles, "$outexpo"; # =================================================== # Open and read the exposure values $fits = SimpleFITS->open("<$outexpo"); die "ERROR: could not open '$outexpo' exposure file for reading" if (! $outexpo ); $fits->move('SPECTRUM'); @livevect = $fits->readcol('COUNTS'); die "ERROR: could not read exposure values from '$outexpo'" if ($fits->status()); $fits->setstatus(0)->close(); if ($#livevect != 5-1) { die "ERROR: Live-time vector is expected to have 5 elements but did not"; } # =================================================== # Check to make sure we can open PHA file $outfits = SimpleFITS->open("+<$outfile"); die "ERROR: could not open '$outfile' for writing" if (! $outfits ); $outfits->move('SPECTRUM'); $hduclas3 = $outfits->readkey('HDUCLAS3'); die "ERROR: could not read HDUCLAS3 keyword " if ($outfits->status()); $hduclas4 = $outfits->readkey('HDUCLAS4'); $outfits->setstatus(0); print "HDUCLAS3 = '$hduclas3'\n" if ($chatter >= 5); print "HDUCLAS4 = '$hduclas4'\n" if ($chatter >= 5); $deadcorr = $outfits->readkey('DEADAPP'); if ($outfits->status() == 0 && $deadcorr) { die "ERROR: output file '$outfile' is already dead-time corrected"; } $outfits->setstatus(0); $ontime = $outfits->readkey("EXPOSURE"); die "ERROR: could not read 'EXPOSURE' keyword " if ($outfits->status()); print " SAEXTRCT-reported on-time: $ontime [s]\n\n" if ($chatter >= 2); # =================================================== # This is a "Type:II" spectrum with one spectrum per row if ($hduclas3 =~ m/type:ii/i || $hduclas4 =~ m/type:ii/i) { @rowid = $outfits->readcol('ROWID'); die "ERROR: could not read ROWID column of spectrum" if ($outfits->status()); # Remove the EXPOSURE keyword because it will be a column $outfits->delkey("EXPOSURE"); die "ERROR: could not delete 'EXPOSURE' keyword " if ($outfits->status()); # Remove any existing columns (there shouldn't be these columns anyway!) $outfits->delcol("ONTIME") if ($outfits->colnum("ONTIME") >= 0); $outfits->delcol("EXPOSURE") if ($outfits->colnum("EXPOSURE") >= 0); # ... and create new columns for per spectrum exposure/on-time $outfits->insertcol({TTYPE => ["ONTIME", "Detector on-time"], TFORM => "1D", TUNIT => "s"}) ->insertcol({TTYPE => ["EXPOSURE", "Dead-time corrected exposure"], TFORM => "1D", TUNIT => "s"}); die "ERROR: could not create EXPOSURE/ONTIME columns" if ($outfits->status()); print " Row Column Live-Time\n" if ($chatter >= 2); print "---------------------------------\n" if ($chatter >= 2); for $i (0 .. $#rowid) { $rownum = $i+1; $expo = $ontime; if ("$rowid[$i]" =~ m/^X.*Pcu([0-4])$/) { $pcu = $1; $expo = $livevect[$pcu]; } print " $rownum $rowid[$i] $expo\n" if ($chatter >= 2); $outfits->writecol("EXPOSURE", {rows=>$rownum}, $expo); $outfits->writecol("ONTIME", {rows=>$rownum}, $ontime); } die "ERROR: could not write EXPOSURE column" if ($outfits->status()); # =================================================== # This is a "Type:I" spectrum with one spectrum per extension } else { @pcu_used = (0,0,0,0,0); # Scan through the header and find keywords of the form ROWID*. # Determine how many PCUs were included. $outfits->readheader($header, clean => 1); for $i (0 .. 999) { $key = "ROWID$i"; $val = $header->{$key}; if (defined($val)) { if ("$val" =~ m/^X.*Pcu([0-4]) *$/) { $pcu = $1; $pcu_used[$pcu] = 1; print "$key = '$val' (PCU=$pcu)\n" if ($chatter >=5); } } } # Calculate the cumulative exposure over all five PCUs $npcu = 0; $expo = 0.0; print " PCU Used? Live-Time\n" if ($chatter >= 2); print "-----------------------------\n" if ($chatter >= 2); foreach $pcu (0 .. 4) { $used = $pcu_used[$pcu] ? 'Y' : 'N'; $pcu_wt[$pcu] = 0.0; print " $pcu $used $livevect[$pcu]\n" if ($chatter >= 2); if ($used eq 'Y') { if ($livevect[$pcu] <= 0) { print "NOTE: PCU $pcu was included by SAEXTRCT with zero ONTIME\n"; } else { $npcu = $npcu + 1; $expo = $expo + $livevect[$pcu]; $pcu_wt[$pcu] = 1.0; # XXX placeholder } } } # Compute weights for each PCU, which are: # Weight[i] = (PCUi live time) / (Total live time) # When the responses are added by 'addrmf' the sum of # the weights will produce a weighted sum of exposure. if ($expo <= 0 || $npcu <= 0) { warn "WARNING: no valid ONTIME was found "; } foreach $pcu (0 .. 4) { if ($pcu_wt[$pcu] == 1.0) { $pcu_wt[$pcu] = $livevect[$pcu] / $expo; } $outfits->writekey("PCU_WT$pcu",$pcu_wt[$pcu], "PCU $pcu response weight factor"); } $outfits->writekey("ONTIME",$ontime,"Detector on-time"); $outfits->writekey("EXPOSURE",$expo,"Deadtime-corrected exposure"); die "ERROR: could not write ONTIME/EXPOSURE keywords" if ($outfits->status()); } if ($deadcorrtype eq 'LIVE') { $outfits->writekey("DEADAPP", 1, 'Spectrum is dead-time corrected', TLOGICAL); } $outfits->close(); # Remove the final output file from the scratch list # because it is in good shape shift(@scratchfiles) if ($scratchfiles[0] eq "$outfile"); return 0; }