Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
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)
Ejemplo n.º 3
0
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)