def __init__(self, filename): self.filename = filename self.cands = {} self.badcands_knownbirds = [] self.badcands_longperiod = [] self.badcands_shortperiod = [] self.badcands_threshold = [] self.badcands_harmpowcutoff = [] self.badcands_rogueharmpow = [] current_goodcandnum = 0 # First identify the length of the observation searched for line in open(filename, "r"): if line.startswith(" Number of bins in the time series"): self.N = int(line.split()[-1]) if line.startswith(" Width of each time series bin (sec)"): self.dt = float(line.split()[-1]) self.T = self.N * self.dt for line in open(filename, "r"): # Identify the candidates in the top of the file if fund_re.match(line): split_line = line.split() candnum = int(split_line[0]) sigma = float(split_line[1]) i_pow_det = float(split_line[2]) c_pow = float(split_line[3]) numharm = int(split_line[4]) bin = float(split_line[7].split("(")[0]) z = float(split_line[9].split("(")[0]) f = bin / self.T # Spin freq in hz p = 1.0 / f # Spin period in sec # Reject very long period candidates if p > long_period: self.badcands_longperiod.append(candnum) continue # Reject very short period candidates if p < short_period: self.badcands_shortperiod.append(candnum) continue # Check to see if the candidate is in the known birds list known_bird = 0 for bird, err in known_birds_f: if Num.fabs(f - bird) < err: known_bird = 1 break if known_bird: self.badcands_knownbirds.append(candnum) continue for bird, err in known_birds_p: if Num.fabs(p * 1000.0 - bird) < err: known_bird = 1 break if known_bird: self.badcands_knownbirds.append(candnum) continue # Add it to the candidates list DMstr = DM_re.search(filename).groups()[0] self.cands[candnum] = candidate( candnum, sigma, numharm, i_pow_det, c_pow, bin, z, DMstr, filename, self.T ) continue # Parse the harmonic powers elif harms_re.match(line): split_line = line.split() candnum = int(split_line[0]) # Only read the harmonics for the candidates that weren't # rejected in the initial pass if self.cands.has_key(candnum): self.cands[candnum].harm_pows = Num.zeros(self.cands[candnum].numharm, dtype=Num.float64) self.cands[candnum].harm_amps = Num.zeros(self.cands[candnum].numharm, dtype=Num.complex64) power = parse_power(split_line[3]) phase = float(split_line[9].split("(")[0]) self.cands[candnum].harm_pows[0] = power self.cands[candnum].harm_amps[0] = Num.sqrt(power) * Num.exp(phase * 1.0j) if self.cands[candnum].numharm > 1: current_goodcandnum = candnum current_harmnum = 1 else: current_goodcandnum = 0 # Compute the S/N self.cands[candnum].harms_to_snr() # These are the "optimized" power... opt_ipow = self.cands[candnum].harm_pows[0] # and sigma (calculated assuming _1_ trial!) opt_sigma = candidate_sigma(opt_ipow, 1, 1) self.cands[candnum].sigma = opt_sigma self.cands[candnum].ipow_det = opt_ipow # Remove the single harmonic candidates that # don't pass our threshold if opt_sigma < sigma_threshold and self.cands[candnum].cpow < c_pow_threshold: self.badcands_threshold.append(candnum) del (self.cands[candnum]) continue # Parse the higher (than the first) harmonic powers if current_goodcandnum: cand = self.cands[current_goodcandnum] power = parse_power(line.split()[2]) phase = float(line.split()[8].split("(")[0]) cand.harm_pows[current_harmnum] = power cand.harm_amps[current_harmnum] = Num.sqrt(power) * Num.exp(phase * 1.0j) current_harmnum += 1 # Do the more advanced sifting after all the harmonics # have been read in if current_harmnum == cand.numharm: # Compute the S/N cand.harms_to_snr() # Insure that the sum of the optimized powers is > threshold opt_ipow = sum(cand.harm_pows) # Try to correct for the fact that by optimizing each # harmonic power, we get a power that is slightly higher # than it should be. Simulations suggest that the average # increase in power is ~2 per hamonic. For single harmonics, # though, the optimized power should be correct. So the # correction should be approx -2*(cand.numharm-1) opt_sigma = candidate_sigma(opt_ipow - 2.0 * (cand.numharm - 1), cand.numharm, 1) self.cands[current_goodcandnum].sigma = opt_sigma self.cands[current_goodcandnum].ipow_det = opt_ipow if opt_sigma < sigma_threshold: self.badcands_threshold.append(current_goodcandnum) del (self.cands[current_goodcandnum]) current_goodcandnum = 0 continue # Remove the candidates where the harmonic with the # highest power is not more than harm_pow_cutoff maxharm = Num.argmax(cand.harm_pows) maxpow = cand.harm_pows[maxharm] if maxpow < harm_pow_cutoff: self.badcands_harmpowcutoff.append(current_goodcandnum) del (self.cands[current_goodcandnum]) current_goodcandnum = 0 continue # Sort the harmonics by power sortedpows = Num.sort(cand.harm_pows) # Remove cands which are dominated by a single high-power # but high-numbered harmonic if cand.numharm >= 8 and maxharm > 4 and maxpow > 2 * sortedpows[-2]: self.badcands_rogueharmpow.append(current_goodcandnum) del (self.cands[current_goodcandnum]) current_goodcandnum = 0 continue elif cand.numharm >= 4 and maxharm > 2 and maxpow > 3 * sortedpows[-2]: self.badcands_rogueharmpow.append(current_goodcandnum) del (self.cands[current_goodcandnum]) current_goodcandnum = 0 continue current_goodcandnum = 0 continue
def candlist_from_candfile(filename): # First identify the length of the observation searched for line in open(filename, 'r'): if line.startswith(" Number of bins in the time series"): numsamp = int(line.split()[-1]) if line.startswith(" Width of each time series bin (sec)"): dt = float(line.split()[-1]) tobs = numsamp * dt cands = [] candnums = [] current_goodcandnum = 0 for line in open(filename, 'r'): # Identify the candidates in the top of the file if fund_re.match(line): split_line = line.split() candnum = int(split_line[0]) sigma = float(split_line[1]) i_pow_det = float(split_line[2]) c_pow = float(split_line[3]) numharm = int(split_line[4]) bin = float(split_line[7].split("(")[0]) z = float(split_line[9].split("(")[0]) f = bin / tobs # Spin freq in hz p = 1.0 / f # Spin period in sec # Add it to the candidates list DMstr = DM_re.search(filename).groups()[0] cands.append(Candidate(candnum, sigma, numharm, i_pow_det, c_pow, bin, z, DMstr, filename, tobs)) candnums.append(candnum) continue # Parse the harmonic powers elif harms_re.match(line): split_line = line.split() candnum = int(split_line[0]) if candnum in candnums: cand = cands[candnums.index(candnum)] cand.harm_pows = Num.zeros(cand.numharm, dtype=Num.float64) cand.harm_amps = Num.zeros(cand.numharm, dtype=Num.complex64) power = parse_power(split_line[3]) phase = float(split_line[9].split("(")[0]) cand.harm_pows[0] = power cand.harm_amps[0] = Num.sqrt(power) * Num.exp(phase*1.0j) if (cand.numharm > 1): current_goodcandnum = candnum current_harmnum = 1 else: current_goodcandnum = 0 # Compute the S/N cand.harms_to_snr() # Now that S/N is available # List candidate as a hit of itself cand.hits = [(cand.DM, cand.snr)] # These are the "optimized" power... opt_ipow = cand.harm_pows[0] # and sigma (calculated assuming _1_ trial!) opt_sigma = candidate_sigma(opt_ipow, 1, 1) cand.sigma = opt_sigma cand.ipow_det = opt_ipow continue # Parse the higher (than the first) harmonic powers if current_goodcandnum: cand = cands[candnums.index(current_goodcandnum)] power = parse_power(line.split()[2]) phase = float(line.split()[8].split("(")[0]) cand.harm_pows[current_harmnum] = power cand.harm_amps[current_harmnum] = Num.sqrt(power) * Num.exp(phase*1.0j) current_harmnum += 1 # Calculate other stats after all harmonics have been read in if (current_harmnum==cand.numharm): # Compute the S/N cand.harms_to_snr() # Now that S/N is available # List candidate as a hit of itself cand.hits = [(cand.DM, cand.snr)] # Compute sigma and incoherent power opt_ipow = sum(cand.harm_pows) opt_sigma = candidate_sigma(opt_ipow, cand.numharm, 1) cand.sigma = opt_sigma cand.ipow_det = opt_ipow current_goodcandnum = 0 return Candlist(cands)
def candlist_from_candfile(filename): # First identify the length of the observation searched for line in open(filename, 'r'): if line.startswith(" Number of bins in the time series"): numsamp = int(line.split()[-1]) if line.startswith(" Width of each time series bin (sec)"): dt = float(line.split()[-1]) tobs = numsamp * dt cands = [] candnums = [] current_goodcandnum = 0 for line in open(filename, 'r'): # Identify the candidates in the top of the file if fund_re.match(line): split_line = line.split() candnum = int(split_line[0]) sigma = float(split_line[1]) i_pow_det = float(split_line[2]) c_pow = float(split_line[3]) numharm = int(split_line[4]) bin = float(split_line[7].split("(")[0]) z = float(split_line[9].split("(")[0]) f = bin / tobs # Spin freq in hz p = 1.0 / f # Spin period in sec # Add it to the candidates list DMstr = DM_re.search(filename).groups()[0] cands.append( Candidate(candnum, sigma, numharm, i_pow_det, c_pow, bin, z, DMstr, filename, tobs)) candnums.append(candnum) continue # Parse the harmonic powers elif harms_re.match(line): split_line = line.split() candnum = int(split_line[0]) if candnum in candnums: cand = cands[candnums.index(candnum)] cand.harm_pows = Num.zeros(cand.numharm, dtype=Num.float64) cand.harm_amps = Num.zeros(cand.numharm, dtype=Num.complex64) power = parse_power(split_line[3]) phase = float(split_line[9].split("(")[0]) cand.harm_pows[0] = power cand.harm_amps[0] = Num.sqrt(power) * Num.exp(phase * 1.0j) if (cand.numharm > 1): current_goodcandnum = candnum current_harmnum = 1 else: current_goodcandnum = 0 # Compute the S/N cand.harms_to_snr() # Now that S/N is available # List candidate as a hit of itself cand.hits = [(cand.DM, cand.snr)] # These are the "optimized" power... opt_ipow = cand.harm_pows[0] # and sigma (calculated assuming _1_ trial!) opt_sigma = candidate_sigma(opt_ipow, 1, 1) cand.sigma = opt_sigma cand.ipow_det = opt_ipow continue # Parse the higher (than the first) harmonic powers if current_goodcandnum: cand = cands[candnums.index(current_goodcandnum)] power = parse_power(line.split()[2]) phase = float(line.split()[8].split("(")[0]) cand.harm_pows[current_harmnum] = power cand.harm_amps[current_harmnum] = Num.sqrt(power) * Num.exp( phase * 1.0j) current_harmnum += 1 # Calculate other stats after all harmonics have been read in if (current_harmnum == cand.numharm): # Compute the S/N cand.harms_to_snr() # Now that S/N is available # List candidate as a hit of itself cand.hits = [(cand.DM, cand.snr)] # Compute sigma and incoherent power opt_ipow = sum(cand.harm_pows) opt_sigma = candidate_sigma(opt_ipow, cand.numharm, 1) cand.sigma = opt_sigma cand.ipow_det = opt_ipow current_goodcandnum = 0 return Candlist(cands)