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,6 +346,8 @@ def find_peak(self, freqs, results, interpolation='gaussian'):
342346 freq_index , cp_samples = np .unravel_index (results .argmax (),
343347 results .shape )
344348
349+ code_phase = float (cp_samples ) / self .samples_per_chip
350+
345351 if freq_index > 1 and freq_index < len (freqs ) - 1 :
346352 delta = self .interpolate (
347353 results [freq_index - 1 ][cp_samples ],
@@ -358,8 +364,6 @@ def find_peak(self, freqs, results, interpolation='gaussian'):
358364 else :
359365 freq = freqs [freq_index ]
360366
361- code_phase = float (cp_samples ) / self .samples_per_chip
362-
363367 # Calculate SNR for the peak.
364368 results_mean = np .mean (results )
365369 if results_mean != 0 :
@@ -370,7 +374,8 @@ def find_peak(self, freqs, results, interpolation='gaussian'):
370374 return (code_phase , freq , snr )
371375
372376 def acquisition (self ,
373- prns = range (32 ),
377+ prns = xrange (32 ),
378+ channels = [x - 7 for x in xrange (14 )],
374379 doppler_priors = None ,
375380 doppler_search = 7000 ,
376381 doppler_step = None ,
@@ -379,10 +384,10 @@ def acquisition(self,
379384 multi = True
380385 ):
381386 """
382- Perform an acquisition for a given list of PRNs.
387+ Perform an acquisition for a given list of PRNs/channels .
383388
384- Perform an acquisition for a given list of PRNs across a range of Doppler
385- frequencies.
389+ Perform an acquisition for a given list of PRNs/channels across a range of
390+ Doppler frequencies.
386391
387392 This function returns :class:`AcquisitionResult` objects containing the
388393 location of the acquisition peak for PRNs that have an acquisition
@@ -394,8 +399,13 @@ def acquisition(self,
394399
395400 Parameters
396401 ----------
402+ bandcode : optional
403+ String defining the acquisition code. Default: L1CA
404+ choices: L1CA, GLO_L1 (in gps_constants.py)
397405 prns : iterable, optional
398406 List of PRNs to acquire. Default: 0..31 (0-indexed)
407+ channels : iterable, optional
408+ List of channels to acquire. Default: -7..6
399409 doppler_prior: list of floats, optional
400410 List of expected Doppler frequencies in Hz (one per PRN). Search will be
401411 centered about these. If None, will search around 0 for all PRNs.
@@ -413,10 +423,11 @@ def acquisition(self,
413423 Returns
414424 -------
415425 out : [AcquisitionResult]
416- A list of :class:`AcquisitionResult` objects, one per PRN in `prns`.
426+ A list of :class:`AcquisitionResult` objects, one per PRN in `prns` or
427+ channel in 'channels'.
417428
418429 """
419- logger .info ("Acquisition starting" )
430+ logger .info ("Acquisition starting for " + self . signal )
420431 from peregrine .parallel_processing import parmap
421432
422433 # If the Doppler step is not specified, compute it from the coarse
@@ -428,9 +439,6 @@ def acquisition(self,
428439 # magnitude.
429440 doppler_step = self .sampling_freq / self .n_integrate
430441
431- if doppler_priors is None :
432- doppler_priors = np .zeros_like (prns )
433-
434442 if progress_bar_output == 'stdout' :
435443 show_progress = True
436444 progress_fd = sys .stdout
@@ -446,33 +454,55 @@ def acquisition(self,
446454 show_progress = False
447455 logger .warning ("show_progress = True but progressbar module not found." )
448456
457+ if self .signal == L1CA :
458+ input_len = len (prns )
459+ offset = 1
460+ pb_attr = progressbar .Attribute ('prn' , '(PRN: %02d)' , '(PRN --)' )
461+ if doppler_priors is None :
462+ doppler_priors = np .zeros_like (prns )
463+ else :
464+ input_len = len (channels )
465+ offset = 0
466+ pb_attr = progressbar .Attribute ('ch' , '(CH: %02d)' , '(CH --)' )
467+ if doppler_priors is None :
468+ doppler_priors = np .zeros_like (channels )
469+
449470 # Setup our progress bar if we need it
450471 if show_progress and not multi :
451472 widgets = [' Acquisition ' ,
452- progressbar . Attribute ( 'prn' , '(PRN: %02d)' , '(PRN --)' ) , ' ' ,
473+ pb_attr , ' ' ,
453474 progressbar .Percentage (), ' ' ,
454475 progressbar .ETA (), ' ' ,
455476 progressbar .Bar ()]
456477 pbar = progressbar .ProgressBar (widgets = widgets ,
457- maxval = int (len ( prns ) *
458- (2 * doppler_search / doppler_step + 1 )),
478+ maxval = int (input_len *
479+ (2 * doppler_search / doppler_step + 1 )),
459480 fd = progress_fd )
460481 pbar .start ()
461482 else :
462483 pbar = None
463484
464485 def do_acq (n ):
465- prn = prns [n ]
486+ if self .signal == L1CA :
487+ prn = prns [n ]
488+ code = caCodes [prn ]
489+ int_f = self .IF
490+ attr = {'prn' : prn + 1 }
491+ else :
492+ ch = channels [n ]
493+ code = GLOCode
494+ int_f = self .IF + ch * glo_l1_step
495+ attr = {'ch' : ch }
466496 doppler_prior = doppler_priors [n ]
467497 freqs = np .arange (doppler_prior - doppler_search ,
468- doppler_prior + doppler_search , doppler_step ) + self . IF
498+ doppler_prior + doppler_search , doppler_step ) + int_f
469499 if pbar :
470500 def progress_callback (freq_num , num_freqs ):
471- pbar .update (n * len (freqs ) + freq_num , attr = { 'prn' : prn + 1 } )
501+ pbar .update (n * len (freqs ) + freq_num , attr = attr )
472502 else :
473503 progress_callback = None
474504
475- coarse_results = self .acquire (caCodes [ prn ] , freqs ,
505+ coarse_results = self .acquire (code , freqs ,
476506 progress_callback = progress_callback )
477507
478508 code_phase , carr_freq , snr = self .find_peak (freqs , coarse_results ,
@@ -485,13 +515,22 @@ def progress_callback(freq_num, num_freqs):
485515 status = 'A'
486516
487517 # 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 )
518+ if self .signal == L1CA :
519+ acq_result = AcquisitionResult (prn ,
520+ carr_freq ,
521+ carr_freq - int_f ,
522+ code_phase ,
523+ snr ,
524+ status ,
525+ L1CA )
526+ else :
527+ acq_result = GloAcquisitionResult (ch ,
528+ carr_freq ,
529+ carr_freq - int_f ,
530+ code_phase ,
531+ snr ,
532+ status ,
533+ GLO_L1 )
495534
496535 # If the acquisition was successful, log it
497536 if (snr > threshold ):
@@ -501,9 +540,9 @@ def progress_callback(freq_num, num_freqs):
501540
502541 if multi :
503542 acq_results = parmap (
504- do_acq , range ( len ( prns ) ), show_progress = show_progress )
543+ do_acq , xrange ( input_len ), show_progress = show_progress )
505544 else :
506- acq_results = map (do_acq , range ( len ( prns ) ))
545+ acq_results = map (do_acq , xrange ( input_len ))
507546
508547 # Acquisition is finished
509548
@@ -512,9 +551,11 @@ def progress_callback(freq_num, num_freqs):
512551 pbar .finish ()
513552
514553 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 )
554+ acq = [ar .prn + offset for ar in acq_results if ar .status == 'A' ]
555+ if self .signal == L1CA :
556+ logger .info ("Acquired %d satellites, PRNs: %s." , len (acq ), acq )
557+ else :
558+ logger .info ("Acquired %d channels: %s." , len (acq ), acq )
518559
519560 return acq_results
520561
@@ -531,7 +572,7 @@ def save_wisdom(self, wisdom_file=DEFAULT_WISDOM_FILE):
531572 pyfftw .export_wisdom (), f , protocol = cPickle .HIGHEST_PROTOCOL )
532573
533574
534- class AcquisitionResult :
575+ class AcquisitionResult ( object ) :
535576 """
536577 Stores the acquisition parameters of a single satellite.
537578
@@ -560,7 +601,7 @@ class AcquisitionResult:
560601 """
561602
562603 __slots__ = ('prn' , 'carr_freq' , 'doppler' ,
563- 'code_phase' , 'snr' , 'status' , 'signal' )
604+ 'code_phase' , 'snr' , 'status' , 'signal' , 'sample_index' )
564605
565606 def __init__ (self , prn , carr_freq , doppler , code_phase , snr , status , signal ,
566607 sample_index = 0 ):
@@ -574,7 +615,7 @@ def __init__(self, prn, carr_freq, doppler, code_phase, snr, status, signal,
574615 self .sample_index = sample_index
575616
576617 def __str__ (self ):
577- return "PRN %2d (%s) SNR %6.2f @ CP %6.1f , %+8.2f Hz %s" % \
618+ return "PRN %2d (%s) SNR %6.2f @ CP %6.3f , %+8.2f Hz %s" % \
578619 (self .prn + 1 , self .signal , self .snr , self .code_phase ,
579620 self .doppler , self .status )
580621
@@ -615,6 +656,20 @@ def _equal(self, other):
615656 return True
616657
617658
659+ class GloAcquisitionResult (AcquisitionResult ):
660+
661+ def __init__ (self , channel , carr_freq , doppler , code_phase , snr , status ,
662+ signal , sample_index = 0 ):
663+ super (GloAcquisitionResult , self ).__init__ (channel , carr_freq , doppler ,
664+ code_phase , snr , status ,
665+ signal , sample_index )
666+
667+ def __str__ (self ):
668+ return "CH %2d (%s) SNR %6.2f @ CP %6.3f, %+8.2f Hz %s" % \
669+ (self .prn , self .signal , self .snr , self .code_phase , self .doppler ,
670+ self .status )
671+
672+
618673def save_acq_results (filename , acq_results ):
619674 """
620675 Save a set of acquisition results to a file.
@@ -676,4 +731,5 @@ def print_scores(acq_results, pred, pred_dopp=None):
676731
677732 print "Found %d of %d, mean doppler error = %+5.0f Hz, mean abs err = %4.0f Hz, worst = %+5.0f Hz" \
678733 % (n_match , len (pred ),
679- sum_dopp_err / max (1 , n_match ), sum_abs_dopp_err / max (1 , n_match ), worst_dopp_err )
734+ sum_dopp_err / max (1 , n_match ), sum_abs_dopp_err /
735+ max (1 , n_match ), worst_dopp_err )
0 commit comments