def get_resids(): """Read residuals using 'residuals.py' and return them. """ # Need to check if on 32-bit or 64-bit computer # (the following is a hack to find out if we're on a borg or borgii node) if os.uname()[4]=='i686': # 32-bit computer r = residuals.read_residuals() else: # 64-bit computer # r = residuals.read_residuals_64bit() r = residuals.read_residuals() return r
def get_resids(): """Read residuals using 'residuals.py' and return them. """ # Need to check if on 32-bit or 64-bit computer # (the following is a hack to find out if we're on a borg or borgii node) if os.uname()[4] == 'i686': # 32-bit computer r = residuals.read_residuals() else: # 64-bit computer # r = residuals.read_residuals_64bit() r = residuals.read_residuals() return r
def __init__(self, freqbands=[[0, 'inf']]): """Read TEMPO results (resid2.tmp, tempo.lis, timfile and parfiles) freqbands is a list of frequency pairs to display. """ # Open tempo.lis. Parse it and find input .tim and .par files. Also find output .par file. inputfiles_re = re.compile(r"Input data from (.*\.tim.*), Parameters from (.*\.par.*)") outputfile_re = re.compile(r"Assumed parameters -- PSR (.*)$") tempolisfile = open("tempo.lis") intimfn, inparfn, outparfn = None, None, None for line in tempolisfile: match = inputfiles_re.search(line) if match: intimfn = match.group(1).strip() inparfn = match.group(2).strip() else: match = outputfile_re.search(line) if match: outparfn = "%s.par" % match.group(1).strip() if (intimfn != None) and (inparfn != None) and (outparfn != None): # Found what we're looking for no need to continue parsing the file break tempolisfile.close() # Record filename self.inparfn = inparfn self.outparfn = outparfn self.intimfn = intimfn # Read parfiles self.inpar = par.psr_par(inparfn) self.outpar = par.psr_par(outparfn) # Read residuals # Need to check if on 32-bit or 64-bit computer #(the following is a hack to find out if we're on a borg or borgii node) #PATRICKS QUICK FIX 10/14 - 3/39/11 read_residuals_64bit does not work on nimrod or my machine, but 32bit does... #print os.uname()[4] if True: #os.uname()[4]=='i686': # 32-bit computer r = residuals.read_residuals() else: # 64-bit computer r = residuals.read_residuals_64bit() self.max_TOA = r.bary_TOA.max() self.min_TOA = r.bary_TOA.min() self.freqbands = freqbands self.residuals = {} for lo,hi in self.freqbands: indices = (r.bary_freq>=lo) & (r.bary_freq<hi) self.residuals[get_freq_label(lo, hi)] = \ Resids(r.bary_TOA[indices], r.bary_freq[indices], \ np.arange(r.numTOAs)[indices], r.orbit_phs[indices], \ r.postfit_phs[indices], r.postfit_sec[indices], \ r.prefit_phs[indices], r.prefit_sec[indices], \ r.uncertainty[indices], r.weight[indices], \ self.inpar, self.outpar)
def __init__(self, freqbands): """Read TEMPO results (resid2.tmp, tempo.lis, timfile and parfiles) freqbands is a list of frequency pairs to display. """ # Open tempo.lis. Parse it and find input .tim and .par files. Also find output .par file. inputfiles_re = re.compile( r"Input data from (.*\.tim.*), Parameters from (.*\.par.*)") outputfile_re = re.compile(r"Assumed parameters -- PSR (.*)$") tempolisfile = open("tempo.lis") intimfn, inparfn, outparfn = None, None, None for line in tempolisfile: match = inputfiles_re.search(line) if match: intimfn = match.group(1).strip() inparfn = match.group(2).strip() else: match = outputfile_re.search(line) if match: outparfn = "%s.par" % match.group(1).strip() if (intimfn != None) and (inparfn != None) and (outparfn != None): # Found what we're looking for no need to continue parsing the file break tempolisfile.close() # Record filename self.inparfn = inparfn self.outparfn = outparfn self.intimfn = intimfn # Read parfiles self.inpar = par.psr_par(inparfn) self.outpar = par.psr_par(outparfn) # Read residuals r = residuals.read_residuals() self.max_TOA = r.bary_TOA.max() self.min_TOA = r.bary_TOA.min() if freqbands is None: self.freqbands = find_freq_clusters(r.bary_freq) else: self.freqbands = freqbands self.residuals = {} for lo, hi in self.freqbands: indices = (r.bary_freq >= lo) & (r.bary_freq < hi) self.residuals[get_freq_label(lo, hi)] = \ Resids(r.bary_TOA[indices], r.bary_freq[indices], \ np.arange(r.numTOAs)[indices], r.orbit_phs[indices], \ r.postfit_phs[indices], r.postfit_sec[indices], \ r.prefit_phs[indices], r.prefit_sec[indices], \ r.uncertainty[indices], r.weight[indices], \ self.inpar, self.outpar)
def __init__(self, freqbands): """Read TEMPO results (resid2.tmp, tempo.lis, timfile and parfiles) freqbands is a list of frequency pairs to display. """ # Open tempo.lis. Parse it and find input .tim and .par files. Also find output .par file. inputfiles_re = re.compile( r"Input data from (.*\.tim.*), Parameters from (.*\.par.*)") outputfile_re = re.compile(r"Assumed parameters -- PSR (.*)$") tempolisfile = open("tempo.lis") intimfn, inparfn, outparfn = None, None, None for line in tempolisfile: if line[:15] == "Input data from": sline = line.split() intimfn = sline[3][:-1] # strip the comma intimbase = os.path.splitext(intimfn)[0] inparfn = intimbase + ".par" if sline[6] == 'def' else sline[6] if inparfn[-1] == ".": inparfn = inparfn[:-1] elif line[:15] == "Assumed paramet": outparfn = line.split()[-1] + ".par" if (intimfn != None) and (inparfn != None) and (outparfn != None): # Found what we're looking for no need to continue parsing the file break tempolisfile.close() # Record filename self.inparfn = inparfn self.outparfn = outparfn self.intimfn = intimfn # Read parfiles self.inpar = par.psr_par(inparfn) self.outpar = par.psr_par(outparfn) # Read residuals r = residuals.read_residuals() self.max_TOA = r.bary_TOA.max() self.min_TOA = r.bary_TOA.min() if freqbands is None: self.freqbands = find_freq_clusters(r.bary_freq) else: self.freqbands = freqbands self.residuals = {} for lo, hi in self.freqbands: indices = (r.bary_freq >= lo) & (r.bary_freq < hi) self.residuals[get_freq_label(lo, hi)] = \ Resids(r.bary_TOA[indices], r.bary_freq[indices], \ np.arange(r.numTOAs)[indices], r.orbit_phs[indices], \ r.postfit_phs[indices], r.postfit_sec[indices], \ r.prefit_phs[indices], r.prefit_sec[indices], \ r.uncertainty[indices], r.weight[indices], \ self.inpar, self.outpar)
def __init__(self, freqbands): """Read TEMPO results (resid2.tmp, tempo.lis, timfile and parfiles) freqbands is a list of frequency pairs to display. """ # Open tempo.lis. Parse it and find input .tim and .par files. Also find output .par file. inputfiles_re = re.compile(r"Input data from (.*\.tim.*), Parameters from (.*\.par.*)") outputfile_re = re.compile(r"Assumed parameters -- PSR (.*)$") tempolisfile = open("tempo.lis") intimfn, inparfn, outparfn = None, None, None for line in tempolisfile: if line[:15]=="Input data from": sline = line.split() intimfn = sline[3][:-1] # strip the comma intimbase = os.path.splitext(intimfn)[0] inparfn = intimbase+".par" if sline[6]=='def' else sline[6] if inparfn[-1]==".": inparfn = inparfn[:-1] elif line[:15]=="Assumed paramet": outparfn = line.split()[-1]+".par" if (intimfn != None) and (inparfn != None) and (outparfn != None): # Found what we're looking for no need to continue parsing the file break tempolisfile.close() # Record filename self.inparfn = inparfn self.outparfn = outparfn self.intimfn = intimfn # Read parfiles self.inpar = par.psr_par(inparfn) self.outpar = par.psr_par(outparfn) # Read residuals r = residuals.read_residuals() self.max_TOA = r.bary_TOA.max() self.min_TOA = r.bary_TOA.min() if freqbands is None: self.freqbands = find_freq_clusters(r.bary_freq) else: self.freqbands = freqbands self.residuals = {} for lo,hi in self.freqbands: indices = (r.bary_freq>=lo) & (r.bary_freq<hi) self.residuals[get_freq_label(lo, hi)] = \ Resids(r.bary_TOA[indices], r.bary_freq[indices], \ np.arange(r.numTOAs)[indices], r.orbit_phs[indices], \ r.postfit_phs[indices], r.postfit_sec[indices], \ r.prefit_phs[indices], r.prefit_sec[indices], \ r.uncertainty[indices], r.weight[indices], \ self.inpar, self.outpar)
def __init__(self, freqbands): """Read TEMPO results (resid2.tmp, tempo.lis, timfile and parfiles) freqbands is a list of frequency pairs to display. """ # Open tempo.lis. Parse it and find input .tim and .par files. Also find output .par file. inputfiles_re = re.compile(r"Input data from (.*\.tim.*), Parameters from (.*\.par.*)") outputfile_re = re.compile(r"Assumed parameters -- PSR (.*)$") tempolisfile = open("tempo.lis") intimfn, inparfn, outparfn = None, None, None for line in tempolisfile: match = inputfiles_re.search(line) if match: intimfn = match.group(1).strip() inparfn = match.group(2).strip() else: match = outputfile_re.search(line) if match: outparfn = "%s.par" % match.group(1).strip() if (intimfn != None) and (inparfn != None) and (outparfn != None): # Found what we're looking for no need to continue parsing the file break tempolisfile.close() # Record filename self.inparfn = inparfn self.outparfn = outparfn self.intimfn = intimfn # Read parfiles self.inpar = par.psr_par(inparfn) self.outpar = par.psr_par(outparfn) # Read residuals r = residuals.read_residuals() self.max_TOA = r.bary_TOA.max() self.min_TOA = r.bary_TOA.min() if freqbands is None: self.freqbands = find_freq_clusters(r.bary_freq) else: self.freqbands = freqbands self.residuals = {} for lo,hi in self.freqbands: indices = (r.bary_freq>=lo) & (r.bary_freq<hi) self.residuals[get_freq_label(lo, hi)] = \ Resids(r.bary_TOA[indices], r.bary_freq[indices], \ np.arange(r.numTOAs)[indices], r.orbit_phs[indices], \ r.postfit_phs[indices], r.postfit_sec[indices], \ r.prefit_phs[indices], r.prefit_sec[indices], \ r.uncertainty[indices], r.weight[indices], \ self.inpar, self.outpar)
def __init__(self, freqbands): """Read TEMPO results (resid2.tmp, tempo.lis, timfile and parfiles) freqbands is a list of frequency pairs to display. """ # Open tempo.lis. Parse it and find input .tim and .par files. # Also find output .par file. inputfiles_re = re.compile( r"Input data from (.*\.tim.*), Parameters from (.*\.par.*)") outputfile_re = re.compile(r"Assumed parameters -- PSR (.*)$") tempolisfile = open("tempo.lis") intimfn, inparfn, outparfn = None, None, None for line in tempolisfile: match = inputfiles_re.search(line) if match: intimfn = match.group(1).strip() inparfn = match.group(2).strip() else: match = outputfile_re.search(line) if match: outparfn = "%s.par" % match.group(1).strip() if (intimfn != None) and (inparfn != None) and (outparfn != None): # Found what we're looking for no need to continue parsing the file break tempolisfile.close() self.phase_wraps = {} #self.jump_ranges = [] tim = tempy_io.TOAfile.from_tim_file(intimfn) #tim_ordered_index = np.argsort(tim.TOAs) # if there are phase wraps in the tim file, we want to include those # in the intial plot for tim_wrap_pos in tim.phase_wraps: #wrap_index = tim_ordered_index[tim_wrap_index] wrap_index = tim.get_nTOAs(tim_wrap_pos[0]) + tim_wrap_pos[1] self.phase_wraps[wrap_index] = \ tim.phase_wraps[tim_wrap_pos] # if there are jumps in the tim file, we want to include those in the # initial plot self.jump_ranges = tim.get_jump_ranges() #self.ordered_jump_ranges = tim.get_jump_ranges(chronological=True) # Record filename self.inparfn = inparfn self.outparfn = outparfn self.intimfn = intimfn # Read parfiles self.inpar = par.psr_par(inparfn) self.outpar = par.psr_par(outparfn) # Read residuals r = residuals.read_residuals() self.max_TOA = r.bary_TOA.max() self.min_TOA = r.bary_TOA.min() self.ordered_index = np.argsort(r.bary_TOA) self.ordered_MJDs = r.bary_TOA[self.ordered_index] timfile_index = np.arange(r.numTOAs) if freqbands is None: self.freqbands = find_freq_clusters(r.bary_freq) else: self.freqbands = freqbands self.residuals = {} for lo, hi in self.freqbands: indices = (r.bary_freq >= lo) & (r.bary_freq < hi) self.residuals[get_freq_label(lo, hi)] = \ Resids(r.bary_TOA[indices], r.bary_freq[indices], np.arange(r.numTOAs)[indices], #ordered_index[indices], r.orbit_phs[indices], r.postfit_phs[indices], r.postfit_sec[indices], r.prefit_phs[indices], r.prefit_sec[indices], r.uncertainty[indices], r.weight[indices], self.inpar, self.outpar)
def __init__(self, freqbands): """Read TEMPO results (resid2.tmp, tempo.lis, timfile and parfiles) freqbands is a list of frequency pairs to display. """ # Open tempo.lis. Parse it and find input .tim and .par files. # Also find output .par file. inputfiles_re = re.compile(r"Input data from (.*\.tim.*), Parameters from (.*\.par.*)") outputfile_re = re.compile(r"Assumed parameters -- PSR (.*)$") tempolisfile = open("tempo.lis") intimfn, inparfn, outparfn = None, None, None for line in tempolisfile: match = inputfiles_re.search(line) if match: intimfn = match.group(1).strip() inparfn = match.group(2).strip() else: match = outputfile_re.search(line) if match: outparfn = "%s.par" % match.group(1).strip() if (intimfn != None) and (inparfn != None) and (outparfn != None): # Found what we're looking for no need to continue parsing the file break tempolisfile.close() self.phase_wraps = {} self.jump_ranges = [] tim = tempy_io.TOAset.from_tim_file(intimfn) tim_ordered_index = np.argsort(tim.TOAs) # if there are phase wraps in the tim file, we want to include those # in the intial plot for tim_wrap_index in tim.phase_wraps: wrap_index = tim_ordered_index[tim_wrap_index] self.phase_wraps[wrap_index] = \ tim.phase_wraps[tim_wrap_index] # if there are jumps in the tim file, we want to include those in the # initial plot for tim_jstart,tim_jend in tim.jump_ranges: jstart = tim_ordered_index[tim_jstart] jend = tim_ordered_index[tim_jend] self.jump_ranges.append((jstart, jend)) # Record filename self.inparfn = inparfn self.outparfn = outparfn self.intimfn = intimfn # Read parfiles self.inpar = par.psr_par(inparfn) self.outpar = par.psr_par(outparfn) # Read residuals r = residuals.read_residuals() self.max_TOA = r.bary_TOA.max() self.min_TOA = r.bary_TOA.min() ordered_index = np.argsort(r.bary_TOA) self.ordered_MJDs = r.bary_TOA[ordered_index] if freqbands is None: self.freqbands = find_freq_clusters(r.bary_freq) else: self.freqbands = freqbands self.residuals = {} for lo,hi in self.freqbands: indices = (r.bary_freq>=lo) & (r.bary_freq<hi) self.residuals[get_freq_label(lo, hi)] = \ Resids(r.bary_TOA[indices], r.bary_freq[indices], #np.arange(r.numTOAs)[indices], ordered_index[indices], r.orbit_phs[indices], r.postfit_phs[indices], r.postfit_sec[indices], r.prefit_phs[indices], r.prefit_sec[indices], r.uncertainty[indices], r.weight[indices], self.inpar, self.outpar)
def processTimestamps(mjdTimestamps,parFile,workingDir=os.getcwd(),timingProgram='tempo2',bCleanTempDir=True,verbose=False,timingProgramLog='/dev/null'): ''' Takes in timestamps in unbarycentered MJD format, and runs them through a timing program (tempo/tempo2) to barycenter them and if analyzing a pulsar, to compute phase and pulseNumber for every (photon) timestamp INPUTS: mjdTimestamps - timestamps to be barycentered and/or folded. Presumably in TT(UTC) format parFile - a parameter file with values needed for timing, specific to the observed target. See an example at ARCONS-pipeline/timing/test/B0531+21.par (Crab pulsar) workingDir - a directory where a temporary directory can be created. You must have permission to write to this directory timingProgram - 'tempo2' to run TEMPO2 and 'tempo' to run TEMPO. This determines whether the output is in TCB (tempo2) or TDB (tempo) standard format as well as what pulsar binary models are allowed bCleanTempDir - when finished, the temporary directory created for inputs and outputs is deleted verbose - if True, will print debugging information timingProgramLog - a filename to which the text output of tempo/tempo2 should be written. OUPUTS: Return value is a dictionary with tags: 'baryMjdTimestamps' - the barycentered timestamps in Modified Julian Days. TDB if tempo used, TCB if tempo2 used 'pulsePhases' - the pulsar spin phase at a timestamp as a fraction of a period 'pulseNumbers' - which pulses each timestamp corresponds to relative to the TZR reference time from the par file ''' if not os.path.exists(parFile): print 'ERROR: par file not found!' raise Exception('Par file {} does not exist'.format(parFile)) nTimestamps = len(mjdTimestamps) workingTime = '{:.5f}'.format(time.time()) tempDir = os.path.join(workingDir,'dir'+workingTime) parPath = os.path.abspath(parFile) parFilename = os.path.basename(parPath) #make a temporary directory and switch to it, so the various output files will all be here priorCwd = os.getcwd() while os.path.exists(tempDir): #just in case this process was started at the same time as another, let's check that the #tempDir name isn't already used, and adjust it if needed. tempDir = tempDir + '0' os.mkdir(tempDir) try: os.chdir(tempDir) #make a copy of the par file in the new temp directory, so tempo won't change the original file shutil.copy(parPath,parFilename) if timingProgram == 'tempo2': tempJDPath = 'temp_toa.txt' #input file tempBJDPath = 'temp_bary_toa.txt' #output file #save the timestamps to the tempo2 input file np.savetxt(tempJDPath,mjdTimestamps) #form the tempo2 command using the arcons plugin strCommand = 'tempo2 -gr arcons -f {} -a {} -o {} >> {}'.format(parFilename,tempJDPath,tempBJDPath,timingProgramLog) #run tempo2 if verbose: print 'running timing program',strCommand proc = subprocess.Popen(strCommand,shell=True) proc.wait() if verbose: print 'parsing results' #parse the results tempoOutput = np.loadtxt(tempBJDPath,usecols=[1,2]) nBaryTimestamps = len(tempoOutput) if nBaryTimestamps != nTimestamps: raise Exception('number of photons sent to tempo2 does not match number of photons returned') baryMjdTimestamps = tempoOutput[:,0] phases = tempoOutput[:,1] pulseNumbers = np.array(phases,dtype=np.uint32) pulsePhases = numexpr.evaluate('phases%1.') elif timingProgram == 'tempo': tempJDPath = 'temp_toa.tim' #input file tempPulseNumbersPath = 'pulseNumbers.txt' #optional output file #.tim format ##first line indicates using tempo2 style TOA's with keyword FORMAT #following lines follow the format: #photonLabel observing_frequency toa_mjd(utc) error observatory_site_code #the first toa line will be the reference time TZR, which defines phase 0 #Example: #FORMAT 1 #TZR 0.000000000000 56273.164314974114 0.0 GB #arcons 0.0 56273.163858501241 0.0 PL formatLine = b'FORMAT 1\n' #read reference point TZR from par file parDict = readParFile(parFilename) tzrMjd = parDict['TZRMJD'][0] tzrFreq = parDict['TZRFRQ'][0] tzrSite = parDict['TZRSITE'][0] tzrError = 0. tzrLine = b'TZR {} {} {:.1f} {}\n'.format(tzrFreq,tzrMjd,tzrError,tzrSite) #create the tempo .tim input file with open(tempJDPath,'wb') as tempJDFile: tempJDFile.write(formatLine) tempJDFile.write(tzrLine) toaLine = 'arcons 0.0 %.12f 0.0 PL' #PL for Palomar, frequency=0, label=arcons, error=0 np.savetxt(tempJDFile,mjdTimestamps,fmt=toaLine) paramsToFit = 1 #form the tempo command nToasToAllocate = nTimestamps+1 strCommand = 'tempo -f {} -no {} -m{} -l{} {} >> {}'.format(parFilename,tempPulseNumbersPath,nToasToAllocate,paramsToFit,tempJDPath,timingProgramLog) #Run tempo if verbose: print 'running timing program',strCommand proc = subprocess.Popen(strCommand,shell=True) proc.wait() if verbose: print 'parsing results' #parse barycentered timestamps, pulseNumbers, phases from output files residuals = read_residuals() #the reference TZR is the first photon, remove it baryMjdTimestamps = residuals.bary_TOA[1:] pulsePhases = residuals.prefit_phs[1:] pulseNumbers = np.loadtxt(tempPulseNumbersPath)[1:] #some phases may be reported as negative, positive value would be 1+(-phase) pulsePhases[pulsePhases<0.] = pulsePhases[pulsePhases<0.]+1. if len(baryMjdTimestamps) != nTimestamps or len(pulseNumbers) != nTimestamps or len(pulsePhases) != nTimestamps: print 'number of results doesn\'t match number of input timestamps',nTimestamps,len(pulseNumbers) raise Exception('number of photons sent to tempo ({}) does not match number of photons returned ({})'.format(nTimestamps,len(pulseNumbers))) finally: if bCleanTempDir: if verbose: print 'removing tempDir' shutil.rmtree(tempDir) os.chdir(priorCwd) return {'baryMjdTimestamps':baryMjdTimestamps,'pulsePhases':pulsePhases,'pulseNumbers':pulseNumbers}