def construct(self, file_name, freeze_last_frame=True, time_range=None): cap = cv2.VideoCapture(file_name) self.shape = (int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT)), int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_WIDTH))) fps = cap.get(cv2.cv.CV_CAP_PROP_FPS) self.frame_duration = 1.0 / fps frame_count = int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_COUNT)) if time_range is None: start_frame = 0 end_frame = frame_count else: start_frame, end_frame = [fps * t for t in time_range] frame_count = end_frame - start_frame print("Reading in " + file_name + "...") for count in show_progress(list(range(start_frame, end_frame + 1))): returned, frame = cap.read() if not returned: break # b, g, r = cv2.split(frame) # self.frames.append(cv2.merge([r, g, b])) self.frames.append(frame) cap.release() if freeze_last_frame and len(self.frames) > 0: self.original_background = self.background = self.frames[-1]
def construct(self, file_name, freeze_last_frame = True, time_range = None): cap = cv2.VideoCapture(file_name) self.shape = ( int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT)), int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_WIDTH)) ) fps = cap.get(cv2.cv.CV_CAP_PROP_FPS) self.frame_duration = 1.0/fps frame_count = int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_COUNT)) if time_range is None: start_frame = 0 end_frame = frame_count else: start_frame, end_frame = map(lambda t : fps*t, time_range) frame_count = end_frame - start_frame print "Reading in " + file_name + "..." for count in show_progress(range(start_frame, end_frame+1)): returned, frame = cap.read() if not returned break # b, g, r = cv2.split(frame) # self.frames.append(cv2.merge([r, g, b])) self.frames.append(frame) cap.release() if freeze_last_frame and len(self.frames) > 0: self.original_background = self.background = self.frames[-1]
def ffa_search(counts, dt, period_min, period_max): counts = np.array(counts) pmin = np.floor(period_min / dt) pmax = np.ceil(period_max / dt) bin_periods = None stats = None current_rebin = 1 rebinned_counts = counts for bin_period in show_progress(np.arange(pmin, pmax + 1, dtype=int)): # Only powers of two rebin = int(2**np.floor(np.log2(bin_period / pmin))) if rebin > current_rebin: current_rebin = rebin rebinned_counts = _quick_rebin(counts, current_rebin) # When rebinning, bin_period // current_rebin is the same for nearby # periods if bin_period % current_rebin != 0: continue per, st = ffa(rebinned_counts, bin_period // current_rebin) per *= current_rebin if per[0] == 0: continue elif bin_periods is None: bin_periods = per[:-1] * dt stats = st[:-1] else: bin_periods = np.concatenate((bin_periods, per[:-1] * dt)) stats = np.concatenate((stats, st[:-1])) return bin_periods, stats
def _create_responses(range_z): """Create responses corresponding to different accelerations. This is the implementation of Eq. 39 in Ransom, Eikenberry & Middleditch 2002. See that paper for details Parameters ---------- range_z : int List of z values to be used for the calculation. Returns ------- responses : list List of arrays describing the shape of the response function corresponding to each value of ``range_z``. """ log.info("Creating responses") responses = [] for j, z in enumerate(show_progress(range_z)): # fdot = z / T**2 if (np.abs(z) < 0.01): responses.append(0) continue m = np.max([np.abs(int(2 * z)), 40]) sign = z / np.abs(z) absz = np.abs(z) factor = sign * 1 / np.sqrt(2 * absz) q_ks = np.arange(-m / 2, m / 2 + 1) exponentials = np.exp(1j * np.pi * q_ks**2 / z) Yks = sign * np.sqrt(2 / absz) * q_ks Zks = sign * np.sqrt(2 / absz) * (q_ks + z) # print(Yks, Zks) [SZs, CZs] = special.fresnel(Zks) [SYs, CYs] = special.fresnel(Yks) weights = SZs - SYs + 1j * (CYs - CZs) responses.append(weights * exponentials * factor) return responses
def get_TOAs_from_events(events, folding_length, *frequency_derivatives, **kwargs): """Get TOAs of pulsation. Parameters ---------- events : array-like event arrival times folding_length : float length of sub-intervals to fold *frequency_derivatives : floats pulse frequency, first derivative, second derivative, etc. Other parameters ---------------- pepoch : float, default None Epoch of timing solution, in the same units as ev_times. If none, the first event time is used. mjdref : float, default None Reference MJD template : array-like, default None The pulse template nbin : int, default 16 The number of bins in the profile (overridden by the dimension of the template) timfile : str, default 'out.tim' file to save the TOAs to (if PINT is installed) gti: [[g0_0, g0_1], [g1_0, g1_1], ...] Good time intervals. Defaults to None quick: bool If True, use a quicker fitting algorithms for TOAs. Defaults to False position: `astropy.SkyCoord` object Position of the object Returns ------- toas : array-like list of times of arrival. If ``mjdref`` is specified, they are expressed as MJDs, otherwise in MET toa_err : array-like errorbars on TOAs, in the same units as TOAs. """ import matplotlib.pyplot as plt template = kwargs['template'] if 'template' in kwargs else None mjdref = kwargs['mjdref'] if 'mjdref' in kwargs else None nbin = kwargs['nbin'] if 'nbin' in kwargs else 16 pepoch = kwargs['pepoch'] if 'pepoch' in kwargs else None timfile = kwargs['timfile'] if 'timfile' in kwargs else 'out.tim' gti = kwargs['gti'] if 'gti' in kwargs else None label = kwargs['label'] if 'label' in kwargs else None quick = kwargs['quick'] if 'quick' in kwargs else False position = kwargs['position'] if 'position' in kwargs else None pepoch = assign_value_if_none(pepoch, events[0]) gti = assign_value_if_none(gti, [[events[0], events[-1]]]) # run exposure correction only if there are less than 1000 pulsations # in the interval length = gti.max() - gti.min() expocorr = folding_length < (1000 / frequency_derivatives[0]) if template is not None: nbin = len(template) additional_phase = np.argmax(template) / nbin else: phase, profile, profile_err = \ fold_events(copy.deepcopy(events), *frequency_derivatives, ref_time=pepoch, gtis=copy.deepcopy(gti), expocorr=expocorr, nbin=nbin) fit_pars_save, _, _ = \ fit_profile_with_sinusoids(profile, profile_err, nperiods=1, baseline=True) template = std_fold_fit_func(fit_pars_save, phase) fig = plt.figure() plt.plot(phase, profile, drawstyle='steps-mid') plt.plot(phase, template, drawstyle='steps-mid') plt.savefig(timfile.replace('.tim', '') + '.png') plt.close(fig) # start template from highest bin! # template = np.roll(template, -np.argmax(template)) template *= folding_length / length template_fine = std_fold_fit_func(fit_pars_save, np.arange(0, 1, 0.001)) additional_phase = np.argmax(template_fine) / len(template_fine) starts = np.arange(gti[0, 0], gti[-1, 1], folding_length) toas = [] toa_errs = [] for start in show_progress(starts): stop = start + folding_length good = (events >= start) & (events < stop) events_tofold = events[good] if len(events_tofold) < nbin: continue gtis_tofold = \ copy.deepcopy(gti[(gti[:, 0] < stop) & (gti[:, 1] > start)]) gtis_tofold[0, 0] = start gtis_tofold[-1, 1] = stop local_f = frequency_derivatives[0] for i_f, f in enumerate(frequency_derivatives[1:]): local_f += 1 / np.math.factorial(i_f + 1) * (start - pepoch)**(i_f + 1) * f fder = copy.deepcopy(list(frequency_derivatives)) fder[0] = local_f phase, profile, profile_err = \ fold_events(events_tofold, *fder, ref_time=start, gtis=gtis_tofold, expocorr=expocorr, nbin=nbin) # BAD!BAD!BAD! # [[Pay attention to time reference here. # We are folding wrt pepoch, and calculating TOAs wrt start]] toa, toaerr = \ get_TOA(profile, 1/frequency_derivatives[0], start, template=template, additional_phase=additional_phase, quick=quick, debug=True) toas.append(toa) toa_errs.append(toaerr) toas, toa_errs = np.array(toas), np.array(toa_errs) if mjdref is not None: toas = toas / 86400 + mjdref toa_errs = toa_errs * 1e6 if HAS_PINT: label = assign_value_if_none(label, 'hendrics') toa_list = _load_and_prepare_TOAs(toas, errs_us=toa_errs) # workaround until PR #368 is accepted in pint toa_list.table['clkcorr'] = 0 toa_list.write_TOA_file(timfile, name=label, format='Tempo2') print('TOA(MJD) TOAerr(us)') else: print('TOA(MET) TOAerr(us)') for t, e in zip(toas, toa_errs): print(t, e) return toas, toa_errs
def _calculate_all_convolutions(A, responses, freq_intv_to_search, detlev, debug=False, interbin=False, nproc=4): """Accelerate the initial Fourier transform and find pulsations. This function convolves the initial Fourier transform with the responses corresponding to different amounts of constant acceleration, and searches for signals corresponding to candidate pulsations. Parameters ---------- A : complex array The initial FT, normalized so that || FT ||^2 are Leahy powers. responses : list of complex arrays List of response functions corresponding to different values of constant acceleration. freq_intv_to_search : bool array Mask for ``A``, showing all spectral bins that should be searched for pulsations. Note that we use the full array to calculate the convolution with the responses, but only these bins to search for pulsations. Had we filtered the frequencies before the convolution, we would be sure to introduce boundary effects in the "Good" frequency interval detlev : float The power level considered good for detection Other parameters ---------------- debug : bool Dump debugging information interbin : bool Calculate interbinning to improve sensitivity to frequencies close to the edge of PDS bins nproc : int Number of processors to be used for parallel computation. Returns ------- candidate_rs: array of float Frequency of candidates in units of r = 1 / T candidate_js: array of float Index of the response used candidate_powers: array of float Power of candidates """ log.info("Convolving FFT with responses...") candidate_powers = [0.] candidate_rs = [1] candidate_js = [2] # print(responses) len_responses = len(responses) # if debug: # fobj = open('accelsearch_dump.dat', 'w') _, memmapfname = tempfile.mkstemp(suffix='.npy') memout = np.lib.format.open_memmap(memmapfname, mode='w+', dtype=A.dtype, shape=A.shape) from functools import partial func = partial(_convolve_with_response, A, detlev, freq_intv_to_search, interbin=interbin, memout=memout) if nproc == 1: results = [] for j in show_progress(range(len_responses)): results.append(func((responses[j], j))) else: with Pool(processes=nproc) as pool: results = list( show_progress(pool.imap_unordered( func, [(responses[j], j) for j in range(len_responses)]), total=len_responses)) pool.close() for res in results: for subr in res: candidate_powers.append(subr[2]) candidate_rs.append(subr[0]) candidate_js.append(subr[1]) # if debug: # fobj.close() return candidate_rs[1:], candidate_js[1:], candidate_powers[1:]