#!/usr/bin/perl # # t2t2 # IHS May 30, 2009: Check for FUTs in Princeton-format TOAs # and convert to MJDs. Leave commented-out toas with "C" # rather than "I" as there are parsing issues if the input "C" # replaces a column, and then tempo2 dies on trying to read an # "ignored" TOA -- not worth fixing today! # Also allow user to replace a site number/letter with new-style # longer codes. # # IHS July 4, 2008: minor bug fixes: prints out overridden ID now # even if there was a usable ID to begin with. Also correctly # prints out requested extra flags in the absence of JUMPs # # IHS, March 6, 2007, borrowing from various sources including # several DJN scripts. # # Converts tempo1-format toa files to tempo2 format. # Should be able to handle Parkes, Jodrell, ITOA and Princeton # format toas, including cases where not all columns on # Princeton-format toas are used. # # As per email from George Hobbs, March 6 2007: # # A tempo2 file must have as the first line: # # FORMAT 1 # # Then you can use a "C" or "#" at the start of a line for a comment. Each # real observation line must have # # ID FREQ(MHZ) SAT TOAERR(us) TEL_ID # # Where "ID" is an identifier (e.g. pulsar name, filename ...) that does not # contain any white spaces. Each parameter can be as long or as short as # you like and you can leave as many spaces between each parameter. # # Example: # # FORMAT 1 # 1853+13 1402.000 53370.6646017438444 1.48 3 -f asp # 1853+13 1402.000 53393.5956318214029 0.88 3 -f asp # # On the end of the line you can add as many flags as you like. Flags start # with a "-" sign, but can be as long as you like e.g. # # -inst asp -obs ingrid -tel arecibo # # In your parameter file you can then add jumps using (e.g.): # # JUMP -f asp # JUMP -tel arecibo # # end George email # # # This program will take in a toa file (with toas, not with a list of # INCLUDEd files) and rearrange the columns to tempo2 format. # You may add as many flags as you like on the command line; these # will get added to the toa lines as flag listings. # This program will automatically add -info flags with the current # info number (assuming it encounters many INFO lines in the toa file) # UNLESS the INFO is overridden on the command line, in which # case ALL output toa lines will get that info flag, disregarding whatever # INFO lines may actually be in the toa file. # When JUMPs are encountered in the file, an extra `jump` flag # will be appended with an incrementing jump number. # If there are no JUMPs in the toa file, no jump flags will be written out. # When commented-out or SKIPped toas are encountered, the toa line(s) # will be printed out with an initial `I` to be ignored by tempo2. $usage = "Use: t2t2 [options]\n". "Options:\n". " -flag flagname flagvalue (where flagname is not `info` or `jump`; multiple flags allowed)\n". " -id some_id (all ID values will be some_id)\n". " -tel_id telescope-ID (replace all site info with this string)\n". " -info number (to override all info lines in the toa file)\n". " -nodmo (do not write out DM corrections, even if present. Must use this with PRESTO TOAs.)\n". " -type pton/jb/pks/itoa (defaults to assuming pton)\n"; $ttype = 0; @ttstring = ("pton", "jb", "pks", "itoa"); $nflags = 0; $i = 0; $ip = -1; $forceinfo = 0; $setid = 0; $settelid = 0; $newtelid = "random_place"; $idstring = "uninformative"; $njump = 0; $useinfo = 0; $nodmo = 0; if($#ARGV<1) { die $usage; } while($i <= $#ARGV) { # printf "%d %s\n", $i, $ARGV[$i]; if ($ARGV[$i] =~ /^-/) { if ($ARGV[$i] =~ /^-flag/) { $flagname[$nflags] = $ARGV[$i+1]; $flagval[$nflags] = $ARGV[$i+2]; if($flagname[$nflags] =~ /^info$/ || $flagname[$nflags] =~ /^jump$/) { die $usage; } $nflags++; $i+=3; } elsif ($ARGV[$i] =~ /^-id/) { $setid = 1; $idstring = $ARGV[$i+1]; $i+=2; } elsif ($ARGV[$i] =~ /^-tel_id/) { $settelid = 1; $newtelid = $ARGV[$i+1]; $i+=2; } elsif ($ARGV[$i] =~ /^-info/) { $forceinfo = 1; $useinfo = 1; $infoval = $ARGV[$i+1]; # printf "Forcing info to be %d\n", $infoval; $i+=2; } elsif ($ARGV[$i] =~ /^-nodmo/) { $nodmo = 1; $i+=1; } elsif ($ARGV[$i] =~ /^-type/) { if($ARGV[$i+1] =~ /^pton/) { $ttype = 0; } if($ARGV[$i+1] =~ /^jb/) { $ttype = 1; } if($ARGV[$i+1] =~ /^pks/) { $ttype = 2; } if($ARGV[$i+1] =~ /^itoa/) { $ttype = 3; } $i+=2; } else { die $usage; } } else { $ip++; $infile = $ARGV[$i] if ($ip == 0); $outfile = $ARGV[$i] if ($ip == 1); if ($ip>1) { die $usage; } $i++; # printf "%d %d %s %s\n",$i, $ip,$infile,$outfile; } } printf "Will convert file %s to file %s, assuming %s format.\n", $infile, $outfile, $ttstring[$ttype]; printf "Forcing all info flags to %d.\n", $infoval if ($forceinfo == 1); printf "Setting all ID values to %s.\n", $idstring if ($setid == 1); printf "Setting telescope string to %s.\n", $newtelid if ($settelid == 1); if ($nflags > 0) { printf "Appending the following flags:\n"; for ($iflag=0; $iflag<$nflags;$iflag++) { printf " -%s %s",$flagname[$iflag],$flagval[$iflag] } printf "\n"; } open (OUT, ">$outfile") || die "Cannot open $outfile for writing: $!"; open (IN, "$infile") || die "Cannot open $infile for reading: $!"; printf OUT "FORMAT 1\n\n"; $ignoreline = 0; $jumppair = 0; while() { chomp; $len = length($_); $col1 = substr($_,0,1); # printf "%s has length %3d and first column %s\n",$_,$len,$col1; $id = sprintf "nothingyet"; $freq = -200.; $toa = 1.0; $toaerr = 1.0; $site = "Q"; $dmo = 0.; $istoa = 0; $toaline = 0; $singlebad = 0; if($len > 1) { # Don't deal with blank lines # printf "%s\n%2d: Toa, istoa, ignore, singlebad,jumppair: %1d %1d %1d %1d %1d\n",$_,1,$toaline,$istoa,$ignoreline,$singlebad,$jumppair; if($col1 =~ /C/) { # Either a comment line or a commented-out TOA $rest = substr($_,0,$len); $lenr = $len; while ($istoa == 0 && $lenr > 30) { # See if the rest of the line # should be interpreted as a commented-out TOA $rest = substr($rest,1,$lenr); $lenr = $lenr-1; $istoa = &toaparse($rest); if($istoa == 1) { # To be written out later, with flags and `I` $toaline = 1; $singlebad = 1; # printf "I think this is a commented-out TOA:\n %s %12.5f %s %s %1s\nValues of toaline, singlebad and ignoreline are: %d %d %d\n", $id,$freq,$toa,$toaerr,$site,$toaline,$singlebad,$ignoreline; # break; } } # printf "%s\n%2d: Toa, istoa, ignore, singlebad,jumppair: %1d %1d %1d %1d %1d\n",$_,2,$toaline,$istoa,$ignoreline,$singlebad,$jumppair; if($istoa == 0) { # Looks like a comment -- just write it out printf OUT "%s\n", $_; $toaline = 0; $singlebad = 0; } # printf "%s\n%2d: Toa, istoa, ignore, singlebad,jumppair: %1d %1d %1d %1d %1d\n",$_,3,$toaline,$istoa,$ignoreline,$singlebad,$jumppair; } else { # Check to see if we have a TOA command; treat as needed ($firstword) = split; # printf "Trying to figure out what to do with %s\n",$firstword; if($firstword =~ /^SKIP$/) { $toaline = 0; $ignoreline = 1; } elsif($firstword =~ /^NOSKIP$/) { $toaline = 0; $ignoreline = 0; } elsif($firstword =~ /^MODE$/) { $toaline = 0; } elsif($firstword =~ /^INFO$/) { $toaline = 0; $useinfo = 1; # printf "Caught an INFO flag, value "; if($forceinfo == 0) { ($jnq,$infoval) = split; # printf "%d",$infoval; } # printf "\n"; } elsif($firstword =~ /^JUMP$/) { $toaline = 0; if($jumppair == 0) { $njump++; if($njump == 1) { $flagname[$nflags] = "jump"; $nflags++; } $flagval[$nflags-1] = $njump -1; } $jumppair = 1-$jumppair; } elsif($firstword =~ /^[A-Z]+/ || $firstword =~ /PHA[1-2]/) { # some other command, not treated specially $toaline = 0; printf OUT "%s\n", $_; # printf "%s\n%2d: Toa, istoa, ignore, singlebad,jumppair: %1d %1d %1d %1d %1d\n",$_,4,$toaline,$istoa,$ignoreline,$singlebad,$jumppair; } else { # all other possibilities exhausted -- must be a TOA line $toaline = 1; $success = &toaparse($_); if($success == 0 && $len > 30) { # printf "%s %12.5f %s %s %1s\n", $id,$freq,$toa,$toaerr,$site; die "Bad toa line: $_\nTry another TOA format option."; } # printf "%s\n%2d: Toa, istoa, ignore, singlebad,jumppair: %1d %1d %1d %1d %1d\n",$_,5,$toaline,$istoa,$ignoreline,$singlebad,$jumppair; } } # printf "Time to decide what to do:\n %s %12.5f %s %s %1s\nValues of toaline, singlebad and ignoreline are: %d %d %d\n", $id,$freq,$toa,$toaerr,$site,$toaline,$singlebad,$ignoreline; if($toaline == 1) { if($ignoreline == 1 || $singlebad == 1) { printf OUT "C "; if($singlebad == 1) { $singlebad = 0; } } # if($id =~ /\s*/) { if(!($id =~ /[a-zA-Z1-9]/)) { # ID contains no letters or numbers if($setid == 0) { die "Can't find usable ID value. Rerun with -id option.\n"; } # else { # $id = sprintf "%s", $idstring; # } } if($setid == 1) { $id = sprintf "%s", $idstring; } if($settelid == 1) { $site = sprintf "%s", $newtelid; } printf OUT "%s %12.5f %s %s %s", $id,$freq,$toa,$toaerr,$site; if($dmo != 0. && $nodmo == 0) { printf OUT " -dmo %e", $dmo; } if($useinfo == 1) { printf OUT " -info %1d", $infoval; } if($jumppair==1) { for($iflag=0;$iflag<$nflags;$iflag++) { printf OUT " -%s %s",$flagname[$iflag],$flagval[$iflag]; } } if($jumppair==0) { if($njump > 0) { for($iflag=0;$iflag<$nflags-1;$iflag++) { printf OUT " -%s %s",$flagname[$iflag],$flagval[$iflag]; } } else { for($iflag=0;$iflag<$nflags;$iflag++) { printf OUT " -%s %s",$flagname[$iflag],$flagval[$iflag]; } } } printf OUT "\n"; } } } sub toaparse { my ($line) = ($_[0]); # Use a local variable for the line to be parsed if($ttype == 0) { # Princeton format # From the tempo reference page: # Princeton Format # # columns item # 1-1 Observatory (one-character code) # 2-2 must be blank # 16-24 Observing frequency (MHz) # 25-44 TOA (decimal point must be in column 30 or column 31) # 45-53 TOA uncertainty # 69-78 DM correction (pc cm^-3) $site = substr($line, 0,1); $freq = substr($line, 15,9); $toa = substr($line, 24,20); $toaerr = substr($line, 44,9); $dmo = substr($line, 68,10); $id = substr($line, 6,8); # This will often, but not always, be the case $nscan = substr($line, 1,5); # This will often, but not always, be the case # Parse TOA itself to check for FUT and deal with that if necessary if(substr($toa,5,1) =~/\./ ) { $mjd = substr($toa,0,5); $fracmjd = substr($toa,6,14); #printf "split type-1 toa into %s and %s\n",$mjd,$fracmjd } elsif(substr($toa,6,1) =~/./ ) { $mjd = substr($toa,0,6); $fracmjd = substr($toa,7,13); } if($mjd < 30000) { $mjd += 39126; $toa = sprintf "%5d.%14s", $mjd,$fracmjd; } if(($site =~ /[0-9]/ || $site =~ /[a-z]/ || $site =~ /@/) && $freq > 10.) { return 1; } else { return 0; } } if($ttype == 1) { # JBO format -- essentially the same as Parkes, but # the ID is elsewhere. # From the tempo reference page: # Parkes Format # # columns item # 1-1 must be blank # 26-34 Observing frequency (MHz) # 35-55 TOA (decimal point must be in column 42) # 56-63 Phase offset (fraction of P0, added to TOA) # 64-71 TOA uncertainty # 80-80 Observatory (one-character code) $colcheck = substr($line,0,1); $site = substr($line, 79,1); $freq = substr($line, 25,9); $toa = substr($line, 34,21); $toaerr = substr($line, 63,8); $id = substr($line, 17,8); # This will often, but not always, be the case if($colcheck !~ " ") { # Wrong format return 0; } if(($site =~ /[0-9]/ || $site =~ /[a-z]/ || $site =~ /@/) && $freq > 10.) { return 1; } else { return 0; } } if($ttype == 2) { # Parkes format # From the tempo reference page: # Parkes Format # # columns item # 1-1 must be blank # 26-34 Observing frequency (MHz) # 35-55 TOA (decimal point must be in column 42) # 56-63 Phase offset (fraction of P0, added to TOA) # 64-71 TOA uncertainty # 80-80 Observatory (one-character code) $colcheck = substr($line,0,1); $site = substr($line, 79,1); $freq = substr($line, 25,9); $toa = substr($line, 34,21); $toaerr = substr($line, 63,8); $id = substr($line, 1,18); # This will often, but not always, be the case if($colcheck !~ " ") { # Wrong format return 0; } if(($site =~ /[0-9]/ || $site =~ /[a-z]/ || $site =~ /@/) && $freq > 10.) { return 1; } else { return 0; } } if($ttype == 3) { # ITOA format # From the tempo reference page: # ITOA Format # # columns item # 1-2 ignored, but must not be blank (often PSRNAME goes here) # 10-28 TOA (decimal point must be in column 15) # 29-34 TOA uncertainty # 35-45 Observing frequency (MHz) # 46-55 DM correction (pc cm^-3) # 58-59 Observatory (two-letter code) $colcheck = substr($line,0,1); $sitein = substr($line, 57,2); $freq = substr($line, 34,11); $toa = substr($line, 9,19); $toaerr = substr($line, 28,6); $dmo = substr($line, 45,10); $id = substr($line, 0,9); # This will often, but not always, be the case if($colcheck =~ " ") { # Wrong format return 0; } if(($site =~ /[A-Z][A-Z]/) && $freq > 10.) { $site = sprintf "%sUTC", $sitein; return 1; } else { return 0; } } }