1717import numpy as np
1818import pyfftw
1919import cPickle
20- import defaults
2120
2221from include .generateCAcode import caCodes
22+ from include .generateGLOcode import GLOCode
23+ from peregrine .gps_constants import L1CA
24+ from peregrine .glo_constants import GLO_L1 , glo_l1_step
2325
2426import logging
2527logger = logging .getLogger (__name__ )
@@ -191,13 +193,15 @@ def interpolate(self, S_0, S_1, S_2, interpolation='gaussian'):
191193
192194 **Parabolic interpolation:**
193195
194- .. math:: \Delta = \\ frac{1}{2} \\ frac{S[k+1] - S[k-1]}{2S[k] - S[k-1] - S[k+1]}
196+ .. math:: \Delta = \\ frac{1}{2} \\ frac{S[k+1] -
197+ S[k-1]}{2S[k] - S[k-1] - S[k+1]}
195198
196199 Where :math:`S[n]` is the magnitude of FFT bin :math:`n`.
197200
198201 **Gaussian interpolation:**
199202
200- .. math:: \Delta = \\ frac{1}{2} \\ frac{\ln(S[k+1]) - \ln(S[k-1])}{2\ln(S[k]) - \ln(S[k-1]) - \ln(S[k+1])}
203+ .. math:: \Delta = \\ frac{1}{2} \\ frac{\ln(S[k+1]) -
204+ \ln(S[k-1])}{2\ln(S[k]) - \ln(S[k-1]) - \ln(S[k+1])}
201205
202206 The Gaussian interpolation method gives better results, especially when
203207 used with a Gaussian window function, at the expense of computational
@@ -342,24 +346,39 @@ def find_peak(self, freqs, results, interpolation='gaussian'):
342346 freq_index , cp_samples = np .unravel_index (results .argmax (),
343347 results .shape )
344348
345- if freq_index > 1 and freq_index < len (freqs ) - 1 :
346- delta = self .interpolate (
347- results [freq_index - 1 ][cp_samples ],
348- results [freq_index ][cp_samples ],
349- results [freq_index + 1 ][cp_samples ],
350- interpolation
351- )
352- if delta > 0 :
353- freq = freqs [freq_index ] + \
354- (freqs [freq_index + 1 ] - freqs [freq_index ]) * delta
355- else :
356- freq = freqs [freq_index ] - \
357- (freqs [freq_index - 1 ] - freqs [freq_index ]) * delta
358- else :
359- freq = freqs [freq_index ]
360-
361349 code_phase = float (cp_samples ) / self .samples_per_chip
362350
351+ #print results[freq_index]
352+ #pp(results[freq_index - 6][cp_samples])
353+ #pp(results[freq_index - 5][cp_samples])
354+ #pp(results[freq_index - 4][cp_samples])
355+ #pp(results[freq_index - 3][cp_samples])
356+ #pp(results[freq_index - 2][cp_samples])
357+ #pp(results[freq_index - 1][cp_samples])
358+ #pp(results[freq_index][cp_samples])
359+ #pp(results[freq_index + 1][cp_samples])
360+ #pp(results[freq_index + 2][cp_samples])
361+ #pp(results[freq_index + 3][cp_samples])
362+ #pp(results[freq_index + 4][cp_samples])
363+ #pp(results[freq_index + 5][cp_samples])
364+ #pp(results[freq_index + 6][cp_samples])
365+
366+ #if freq_index > 3 and freq_index < len(freqs) - 3:
367+ #delta = self.interpolate(
368+ #results[freq_index - 3][cp_samples],
369+ #results[freq_index][cp_samples],
370+ #results[freq_index + 3][cp_samples],
371+ #interpolation
372+ #)
373+ #if delta > 0:
374+ #freq = freqs[freq_index] + \
375+ #(freqs[freq_index + 3] - freqs[freq_index]) * delta
376+ #else:
377+ #freq = freqs[freq_index] - \
378+ #(freqs[freq_index - 3] - freqs[freq_index]) * delta
379+ #else:
380+ freq = freqs [freq_index ]
381+
363382 # Calculate SNR for the peak.
364383 results_mean = np .mean (results )
365384 if results_mean != 0 :
@@ -370,7 +389,8 @@ def find_peak(self, freqs, results, interpolation='gaussian'):
370389 return (code_phase , freq , snr )
371390
372391 def acquisition (self ,
373- prns = range (32 ),
392+ prns = xrange (32 ),
393+ channels = [x - 7 for x in xrange (14 )],
374394 doppler_priors = None ,
375395 doppler_search = 7000 ,
376396 doppler_step = None ,
@@ -379,10 +399,10 @@ def acquisition(self,
379399 multi = True
380400 ):
381401 """
382- Perform an acquisition for a given list of PRNs.
402+ Perform an acquisition for a given list of PRNs/channels .
383403
384- Perform an acquisition for a given list of PRNs across a range of Doppler
385- frequencies.
404+ Perform an acquisition for a given list of PRNs/channels across a range of
405+ Doppler frequencies.
386406
387407 This function returns :class:`AcquisitionResult` objects containing the
388408 location of the acquisition peak for PRNs that have an acquisition
@@ -394,8 +414,13 @@ def acquisition(self,
394414
395415 Parameters
396416 ----------
417+ bandcode : optional
418+ String defining the acquisition code. Default: L1CA
419+ choices: L1CA, GLO_L1 (in gps_constants.py)
397420 prns : iterable, optional
398421 List of PRNs to acquire. Default: 0..31 (0-indexed)
422+ channels : iterable, optional
423+ List of channels to acquire. Default: -7..6
399424 doppler_prior: list of floats, optional
400425 List of expected Doppler frequencies in Hz (one per PRN). Search will be
401426 centered about these. If None, will search around 0 for all PRNs.
@@ -413,10 +438,11 @@ def acquisition(self,
413438 Returns
414439 -------
415440 out : [AcquisitionResult]
416- A list of :class:`AcquisitionResult` objects, one per PRN in `prns`.
441+ A list of :class:`AcquisitionResult` objects, one per PRN in `prns` or
442+ channel in 'channels'.
417443
418444 """
419- logger .info ("Acquisition starting" )
445+ logger .info ("Acquisition starting for " + self . signal )
420446 from peregrine .parallel_processing import parmap
421447
422448 # If the Doppler step is not specified, compute it from the coarse
@@ -428,9 +454,6 @@ def acquisition(self,
428454 # magnitude.
429455 doppler_step = self .sampling_freq / self .n_integrate
430456
431- if doppler_priors is None :
432- doppler_priors = np .zeros_like (prns )
433-
434457 if progress_bar_output == 'stdout' :
435458 show_progress = True
436459 progress_fd = sys .stdout
@@ -446,33 +469,55 @@ def acquisition(self,
446469 show_progress = False
447470 logger .warning ("show_progress = True but progressbar module not found." )
448471
472+ if self .signal == L1CA :
473+ input_len = len (prns )
474+ offset = 1
475+ pb_attr = progressbar .Attribute ('prn' , '(PRN: %02d)' , '(PRN --)' )
476+ if doppler_priors is None :
477+ doppler_priors = np .zeros_like (prns )
478+ else :
479+ input_len = len (channels )
480+ offset = 0
481+ pb_attr = progressbar .Attribute ('ch' , '(CH: %02d)' , '(CH --)' )
482+ if doppler_priors is None :
483+ doppler_priors = np .zeros_like (channels )
484+
449485 # Setup our progress bar if we need it
450486 if show_progress and not multi :
451487 widgets = [' Acquisition ' ,
452- progressbar . Attribute ( 'prn' , '(PRN: %02d)' , '(PRN --)' ) , ' ' ,
488+ pb_attr , ' ' ,
453489 progressbar .Percentage (), ' ' ,
454490 progressbar .ETA (), ' ' ,
455491 progressbar .Bar ()]
456492 pbar = progressbar .ProgressBar (widgets = widgets ,
457- maxval = int (len ( prns ) *
458- (2 * doppler_search / doppler_step + 1 )),
493+ maxval = int (input_len *
494+ (2 * doppler_search / doppler_step + 1 )),
459495 fd = progress_fd )
460496 pbar .start ()
461497 else :
462498 pbar = None
463499
464500 def do_acq (n ):
465- prn = prns [n ]
501+ if self .signal == L1CA :
502+ prn = prns [n ]
503+ code = caCodes [prn ]
504+ int_f = self .IF
505+ attr = {'prn' : prn + 1 }
506+ else :
507+ ch = channels [n ]
508+ code = GLOCode
509+ int_f = self .IF + ch * glo_l1_step
510+ attr = {'ch' : ch }
466511 doppler_prior = doppler_priors [n ]
467512 freqs = np .arange (doppler_prior - doppler_search ,
468- doppler_prior + doppler_search , doppler_step ) + self . IF
513+ doppler_prior + doppler_search , doppler_step ) + int_f
469514 if pbar :
470515 def progress_callback (freq_num , num_freqs ):
471- pbar .update (n * len (freqs ) + freq_num , attr = { 'prn' : prn + 1 } )
516+ pbar .update (n * len (freqs ) + freq_num , attr = attr )
472517 else :
473518 progress_callback = None
474519
475- coarse_results = self .acquire (caCodes [ prn ] , freqs ,
520+ coarse_results = self .acquire (code , freqs ,
476521 progress_callback = progress_callback )
477522
478523 code_phase , carr_freq , snr = self .find_peak (freqs , coarse_results ,
@@ -485,13 +530,22 @@ def progress_callback(freq_num, num_freqs):
485530 status = 'A'
486531
487532 # Save properties of the detected satellite signal
488- acq_result = AcquisitionResult (prn ,
489- carr_freq ,
490- carr_freq - self .IF ,
491- code_phase ,
492- snr ,
493- status ,
494- self .signal )
533+ if self .signal == L1CA :
534+ acq_result = AcquisitionResult (prn ,
535+ carr_freq ,
536+ carr_freq - int_f ,
537+ code_phase ,
538+ snr ,
539+ status ,
540+ L1CA )
541+ else :
542+ acq_result = GloAcquisitionResult (ch ,
543+ carr_freq ,
544+ carr_freq - int_f ,
545+ code_phase ,
546+ snr ,
547+ status ,
548+ GLO_L1 )
495549
496550 # If the acquisition was successful, log it
497551 if (snr > threshold ):
@@ -501,9 +555,9 @@ def progress_callback(freq_num, num_freqs):
501555
502556 if multi :
503557 acq_results = parmap (
504- do_acq , range ( len ( prns ) ), show_progress = show_progress )
558+ do_acq , xrange ( input_len ), show_progress = show_progress )
505559 else :
506- acq_results = map (do_acq , range ( len ( prns ) ))
560+ acq_results = map (do_acq , xrange ( input_len ))
507561
508562 # Acquisition is finished
509563
@@ -512,9 +566,11 @@ def progress_callback(freq_num, num_freqs):
512566 pbar .finish ()
513567
514568 logger .info ("Acquisition finished" )
515- acquired_prns = [ar .prn + 1 for ar in acq_results if ar .status == 'A' ]
516- logger .info ("Acquired %d satellites, PRNs: %s." ,
517- len (acquired_prns ), acquired_prns )
569+ acq = [ar .prn + offset for ar in acq_results if ar .status == 'A' ]
570+ if self .signal == L1CA :
571+ logger .info ("Acquired %d satellites, PRNs: %s." , len (acq ), acq )
572+ else :
573+ logger .info ("Acquired %d channels: %s." , len (acq ), acq )
518574
519575 return acq_results
520576
@@ -531,7 +587,7 @@ def save_wisdom(self, wisdom_file=DEFAULT_WISDOM_FILE):
531587 pyfftw .export_wisdom (), f , protocol = cPickle .HIGHEST_PROTOCOL )
532588
533589
534- class AcquisitionResult :
590+ class AcquisitionResult ( object ) :
535591 """
536592 Stores the acquisition parameters of a single satellite.
537593
@@ -560,7 +616,7 @@ class AcquisitionResult:
560616 """
561617
562618 __slots__ = ('prn' , 'carr_freq' , 'doppler' ,
563- 'code_phase' , 'snr' , 'status' , 'signal' )
619+ 'code_phase' , 'snr' , 'status' , 'signal' , 'sample_index' )
564620
565621 def __init__ (self , prn , carr_freq , doppler , code_phase , snr , status , signal ,
566622 sample_index = 0 ):
@@ -574,7 +630,7 @@ def __init__(self, prn, carr_freq, doppler, code_phase, snr, status, signal,
574630 self .sample_index = sample_index
575631
576632 def __str__ (self ):
577- return "PRN %2d (%s) SNR %6.2f @ CP %6.1f , %+8.2f Hz %s" % \
633+ return "PRN %2d (%s) SNR %6.2f @ CP %6.3f , %+8.2f Hz %s" % \
578634 (self .prn + 1 , self .signal , self .snr , self .code_phase ,
579635 self .doppler , self .status )
580636
@@ -615,6 +671,20 @@ def _equal(self, other):
615671 return True
616672
617673
674+ class GloAcquisitionResult (AcquisitionResult ):
675+
676+ def __init__ (self , channel , carr_freq , doppler , code_phase , snr , status ,
677+ signal , sample_index = 0 ):
678+ super (GloAcquisitionResult , self ).__init__ (channel , carr_freq , doppler ,
679+ code_phase , snr , status ,
680+ signal , sample_index )
681+
682+ def __str__ (self ):
683+ return "CH %2d (%s) SNR %6.2f @ CP %6.3f, %+8.2f Hz %s" % \
684+ (self .prn , self .signal , self .snr , self .code_phase , self .doppler ,
685+ self .status )
686+
687+
618688def save_acq_results (filename , acq_results ):
619689 """
620690 Save a set of acquisition results to a file.
@@ -676,4 +746,5 @@ def print_scores(acq_results, pred, pred_dopp=None):
676746
677747 print "Found %d of %d, mean doppler error = %+5.0f Hz, mean abs err = %4.0f Hz, worst = %+5.0f Hz" \
678748 % (n_match , len (pred ),
679- sum_dopp_err / max (1 , n_match ), sum_abs_dopp_err / max (1 , n_match ), worst_dopp_err )
749+ sum_dopp_err / max (1 , n_match ), sum_abs_dopp_err /
750+ max (1 , n_match ), worst_dopp_err )
0 commit comments