@@ -699,21 +699,25 @@ def dac(self, expanded=False, return_res=64, inplace=False):
699
699
700
700
return p_signal
701
701
702
- def calc_adc_params (self ):
702
+ def calc_adc_gain_baseline (self , ch , minvals , maxvals ):
703
703
"""
704
- Compute appropriate adc_gain and baseline parameters for adc
705
- conversion, given the physical signal and the fmts.
704
+ Compute adc_gain and baseline parameters for a given channel.
706
705
707
706
Parameters
708
707
----------
709
- N/A
708
+ ch: int
709
+ The channel that the adc_gain and baseline are being computed for.
710
+ minvals: list
711
+ The minimum values for each channel.
712
+ maxvals: list
713
+ The maximum values for each channel.
710
714
711
715
Returns
712
716
-------
713
- adc_gains : list
714
- List of calculated `adc_gain` values for each channel.
715
- baselines : list
716
- List of calculated `baseline` values for each channel.
717
+ adc_gain : float
718
+ Calculated `adc_gain` value for a given channel.
719
+ baseline : int
720
+ Calculated `baseline` value for a given channel.
717
721
718
722
Notes
719
723
-----
@@ -729,85 +733,132 @@ def calc_adc_params(self):
729
733
for calculated float `adc_gain` values.
730
734
731
735
"""
732
- adc_gains = []
733
- baselines = []
736
+ # Get the minimum and maximum (valid) storage values
737
+ dmin , dmax = _digi_bounds (self .fmt [ch ])
738
+ # add 1 because the lowest value is used to store nans
739
+ dmin = dmin + 1
740
+
741
+ pmin = minvals [ch ]
742
+ pmax = maxvals [ch ]
743
+
744
+ # Figure out digital samples used to store physical samples
745
+
746
+ # If the entire signal is NAN, gain/baseline won't be used
747
+ if pmin == np .nan :
748
+ adc_gain = 1
749
+ baseline = 1
750
+ # If the signal is just one value, store one digital value.
751
+ elif pmin == pmax :
752
+ if pmin == 0 :
753
+ adc_gain = 1
754
+ baseline = 1
755
+ else :
756
+ # All digital values are +1 or -1. Keep adc_gain > 0
757
+ adc_gain = abs (1 / pmin )
758
+ baseline = 0
759
+ # Regular varied signal case.
760
+ else :
761
+ # The equation is: p = (d - b) / g
762
+
763
+ # Approximately, pmax maps to dmax, and pmin maps to
764
+ # dmin. Gradient will be equal to, or close to
765
+ # delta(d) / delta(p), since intercept baseline has
766
+ # to be an integer.
767
+
768
+ # Constraint: baseline must be between +/- 2**31
769
+ adc_gain = (dmax - dmin ) / (pmax - pmin )
770
+ baseline = dmin - adc_gain * pmin
771
+
772
+ # Make adjustments for baseline to be an integer
773
+ # This up/down round logic of baseline is to ensure
774
+ # there is no overshoot of dmax. Now pmax will map
775
+ # to dmax or dmax-1 which is also fine.
776
+ if pmin > 0 :
777
+ baseline = int (np .ceil (baseline ))
778
+ else :
779
+ baseline = int (np .floor (baseline ))
780
+
781
+ # After baseline is set, adjust gain correspondingly.Set
782
+ # the gain to map pmin to dmin, and p==0 to baseline.
783
+ # In the case where pmin == 0 and dmin == baseline,
784
+ # adc_gain is already correct. Avoid dividing by 0.
785
+ if dmin != baseline :
786
+ adc_gain = (dmin - baseline ) / pmin
787
+
788
+ # Remap signal if baseline exceeds boundaries.
789
+ # This may happen if pmax < 0
790
+ if baseline > MAX_I32 :
791
+ # pmin maps to dmin, baseline maps to 2**31 - 1
792
+ # pmax will map to a lower value than before
793
+ adc_gain = (MAX_I32 ) - dmin / abs (pmin )
794
+ baseline = MAX_I32
795
+ # This may happen if pmin > 0
796
+ elif baseline < MIN_I32 :
797
+ # pmax maps to dmax, baseline maps to -2**31 + 1
798
+ adc_gain = (dmax - MIN_I32 ) / pmax
799
+ baseline = MIN_I32
800
+
801
+ return adc_gain , baseline
802
+
803
+ def calc_adc_params (self ):
804
+ """
805
+ Compute appropriate adc_gain and baseline parameters for adc
806
+ conversion, given the physical signal and the fmts.
807
+
808
+ Parameters
809
+ ----------
810
+ N/A
734
811
735
- if np .where (np .isinf (self .p_signal ))[0 ].size :
736
- raise ValueError ("Signal contains inf. Cannot perform adc." )
812
+ Returns
813
+ -------
814
+ adc_gains : list
815
+ List of calculated `adc_gain` values for each channel.
816
+ baselines : list
817
+ List of calculated `baseline` values for each channel
737
818
738
- # min and max ignoring nans, unless whole channel is NAN.
739
- # Should suppress warning message.
740
- minvals = np .nanmin (self .p_signal , axis = 0 )
741
- maxvals = np .nanmax (self .p_signal , axis = 0 )
819
+ """
820
+ adc_gains = []
821
+ baselines = []
742
822
743
- for ch in range (np .shape (self .p_signal )[1 ]):
744
- # Get the minimum and maximum (valid) storage values
745
- dmin , dmax = _digi_bounds (self .fmt [ch ])
746
- # add 1 because the lowest value is used to store nans
747
- dmin = dmin + 1
823
+ if self .p_signal is not None :
824
+ if np .where (np .isinf (self .p_signal ))[0 ].size :
825
+ raise ValueError ("Signal contains inf. Cannot perform adc." )
748
826
749
- pmin = minvals [ch ]
750
- pmax = maxvals [ch ]
827
+ # min and max ignoring nans, unless whole channel is NAN.
828
+ # Should suppress warning message.
829
+ minvals = np .nanmin (self .p_signal , axis = 0 )
830
+ maxvals = np .nanmax (self .p_signal , axis = 0 )
751
831
752
- # Figure out digital samples used to store physical samples
832
+ for ch in range (np .shape (self .p_signal )[1 ]):
833
+ adc_gain , baseline = self .calc_adc_gain_baseline (
834
+ ch , minvals , maxvals
835
+ )
836
+ adc_gains .append (adc_gain )
837
+ baselines .append (baseline )
838
+
839
+ elif self .e_p_signal is not None :
840
+ minvals = []
841
+ maxvals = []
842
+ for ch in self .e_p_signal :
843
+ minvals .append (np .nanmin (ch ))
844
+ maxvals .append (np .nanmax (ch ))
845
+
846
+ if any (x == math .inf for x in minvals ) or any (
847
+ x == math .inf for x in maxvals
848
+ ):
849
+ raise ValueError ("Signal contains inf. Cannot perform adc." )
850
+
851
+ for ch , _ in enumerate (self .e_p_signal ):
852
+ adc_gain , baseline = self .calc_adc_gain_baseline (
853
+ ch , minvals , maxvals
854
+ )
855
+ adc_gains .append (adc_gain )
856
+ baselines .append (baseline )
753
857
754
- # If the entire signal is NAN, gain/baseline won't be used
755
- if pmin == np .nan :
756
- adc_gain = 1
757
- baseline = 1
758
- # If the signal is just one value, store one digital value.
759
- elif pmin == pmax :
760
- if pmin == 0 :
761
- adc_gain = 1
762
- baseline = 1
763
- else :
764
- # All digital values are +1 or -1. Keep adc_gain > 0
765
- adc_gain = abs (1 / pmin )
766
- baseline = 0
767
- # Regular varied signal case.
768
- else :
769
- # The equation is: p = (d - b) / g
770
-
771
- # Approximately, pmax maps to dmax, and pmin maps to
772
- # dmin. Gradient will be equal to, or close to
773
- # delta(d) / delta(p), since intercept baseline has
774
- # to be an integer.
775
-
776
- # Constraint: baseline must be between +/- 2**31
777
- adc_gain = (dmax - dmin ) / (pmax - pmin )
778
- baseline = dmin - adc_gain * pmin
779
-
780
- # Make adjustments for baseline to be an integer
781
- # This up/down round logic of baseline is to ensure
782
- # there is no overshoot of dmax. Now pmax will map
783
- # to dmax or dmax-1 which is also fine.
784
- if pmin > 0 :
785
- baseline = int (np .ceil (baseline ))
786
- else :
787
- baseline = int (np .floor (baseline ))
788
-
789
- # After baseline is set, adjust gain correspondingly.Set
790
- # the gain to map pmin to dmin, and p==0 to baseline.
791
- # In the case where pmin == 0 and dmin == baseline,
792
- # adc_gain is already correct. Avoid dividing by 0.
793
- if dmin != baseline :
794
- adc_gain = (dmin - baseline ) / pmin
795
-
796
- # Remap signal if baseline exceeds boundaries.
797
- # This may happen if pmax < 0
798
- if baseline > MAX_I32 :
799
- # pmin maps to dmin, baseline maps to 2**31 - 1
800
- # pmax will map to a lower value than before
801
- adc_gain = (MAX_I32 ) - dmin / abs (pmin )
802
- baseline = MAX_I32
803
- # This may happen if pmin > 0
804
- elif baseline < MIN_I32 :
805
- # pmax maps to dmax, baseline maps to -2**31 + 1
806
- adc_gain = (dmax - MIN_I32 ) / pmax
807
- baseline = MIN_I32
808
-
809
- adc_gains .append (adc_gain )
810
- baselines .append (baseline )
858
+ else :
859
+ raise Exception (
860
+ "Must supply p_signal or e_p_signal to calc_adc_params"
861
+ )
811
862
812
863
return (adc_gains , baselines )
813
864
0 commit comments