docs: def asym(self,option="",omit="",rebin=1,hist_select=''):
          """Calculate and return the asymmetry for various run types. 
             
          usage: asym(option="",omit="",rebin=1,hist_select='')
              
          Inputs:
              option:         see below for details
              omit:           1f bins to omit if space seperated string in options 
                                  is not feasible. See options description below.
              rebin:          SLR only. Weighted average over 'rebin' bins to 
                                  reduce array length by a factor of rebin. 
              hist_select:    string to specify which histograms get combined into 
                                  making the asymmetry calculation. Deliminate 
                                  with [,] or [;]. Histogram names cannot 
                                  therefore contain either of these characters.
              
          Asymmetry calculation outline (with default detectors) ---------------
          
              Split helicity      (NMR): (F-B)/(F+B) for each
              Combined helicity   (NMR): (r-1)/(r+1)
                  where r = sqrt([(B+)(F-)]/[(F+)(B-)])
              
              Split helicity      (NQR): (R-L)/(R+L) for each
              Combined helicity   (NQR): (r-1)/(r+1)
                  where r = sqrt([(L+)(R-)]/[(R+)(L-)])
              
              Alpha diffusion     (NQR) sum(AL0)/sum(L+R)
              Alpha tagged        (NQR) same as NQR, but using the tagged counters
              
          Histogram Selection ---------------------------------------------------
          
              If we wished to do a simple asymmetry calculation in the form of 
                                      
                                      (F-B)/(F+B)
              
              for each helicity, then 
                                         |--|  |--|   paired counter location
                          hist_select = 'F+,F-,B+,B-'
                                          |-----|       paired helicities
                                             |-----|
              
              for alpha diffusion calculations append the two alpha counters
              
                  hist_select = 'R+,R-,L+,L-,A+,A-
              
              for alpha tagged calculations do the following
              
                  hist_select = 'R+,R-,L+,L-,TR+,TR-,TL+,TL-,nTR+,nTR-,nTL+,nTL-'
                      
                  where TR is the right counter tagged (coincident) with alphas, 
                        TL is the left  counter tagged with alphas, 
                       nTR is the right counter tagged with !alphas (absence of), 
                       nLR is the right counter tagged with !alphas, 
                                            
                    
          Status of Data Corrections --------------------------------------------
              SLR/2H: 
                  Removes prebeam bins. 
                  Subtract mean of prebeam bins from raw counts 
                      (does not treat error propagation from this. Errors are 
                      still treated as Poisson, despite not being integers) 
                      
                  Rebinning: 
                      returned time is average time over rebin range
                      returned asym is weighted mean
                  
              1F: 
                  Allows manual removal of unwanted bins. 
                  
                  Scan Combination:
                      Multiscans are considered as a single scan with long 
                      integration time. Histogram bins are summed according to 
                      their frequency bin, errors are Poisson.
              
              1N:
                  Same as 1F. Uses the neutral beam monitor values to calculate 
                  asymetries in the same manner as the NMR calculation. 
               
              2E: 
                  Prebeam bin removal. 
                  Postbeam bin removal. Assumes beamoff time is 0. 
                  Splits saved 1D histograms into 2D.
                  
                  Asymmetry calculations: 
                      raw: calculated through differences method (as described in 
                          the asymmetry calculation outline)
                      dif: let 0 be the index of the centermost scan in time. dif 
                          asymmetries are then calculated via raw[i+1]-raw[i-1], 
                          where "raw" is as calculated in the above line, for each 
                          of the three types: +,-,combined 
                      sl: take a weighted least squares fit to the two bins prior 
                          and the two bins after the center bin (in time). For 
                          each find the value of the asymmetry at the center time 
                          position. Take the difference: post-prior
                      
          Option List
          
              SLR DESCRIPTIONS --------------------------------------------------
              
              "":     dictionary of 2D numpy arrays keyed by 
                          {"p","n","c","time_s"} for each helicity and combination 
                          (val,err). Default return state for unrecognized options
              "h":    dictionary 2D numpy arrays keyed by {"p","n","time_s"} for 
                          each helicity (val,err).
              "p":    2D np array of up helicity state [time_s,val,err].
              "n":    2D np array of down helicity state [time_s,val,err].
              "c":    2D np array of combined asymmetry [time_s,val,err].
              "ad":   2D np array of alpha diffusion ratio [time_s,val,err].
              "at":   dictionary of alpha tagged asymmetries key:[val,err]. 
                      Keys:
                          
                          'time_s'               : 1D array of times in seconds   
                          'p_wiA','n_wiA','c_wiA': coincident with alpha
                          'p_noA','n_noA','c_noA': coincident with no alpha
                          'p_noT','n_noT','c_noT': untagged
                          
                  where p,n,c refer to pos helicity, neg helicity, combined 
                  helicity respectively. Only in 2h mode. 
                          
              
              1F DESCRIPTIONS ---------------------------------------------------
              
                  all options can include a space deliminated list of bins or 
                  ranges of bins which will be omitted. ex: "raw 1 2 5-20 3"
              
              "":     dictionary of 2D numpy arrays keyed by {p,n,c,freq} for each 
                          helicity and combination [val,err]. Default return state 
                          for unrecognized options.
              "r":    Dictionary of 2D numpy arrays keyed by {p,n} for each 
                          helicity (val,err), but listed by bin, not combined by 
                          frequency. 
              "h":    get unshifted +/- helicity scan-combined asymmetries as a 
                          dictionary {'p':(val,err),'n':(val,err),'freq'}
              "p":    get pos helicity states as tuple, combined by frequency 
                          (freq,val,err)
              "n":    similar to p but for negative helicity states
              "c":    get combined helicity states as tuple (freq,val,err)
              
                          
              2E DESCRIPTIONS ---------------------------------------------------
              
                  Takes no options. Returns a dictionary with the keys: 
               
              'dif_p':    [val,err][frequency] of pos. helicity asymmetry 
              'dif_n':    [ve][f] of negative helicity asymmetry
              'dif_c':    [ve][f] of combined helicity asymmetry
              
              'raw_p':    [ve][f][time] raw asymmetries of each time bin. Pos hel. 
              'raw_n':    [ve][f][t] negative helicity.
              'raw_c':    [ve][f][t] combined helicity
              
              'freq':     [f] frequency values
              'time':     [t] time bin values
                  
              'sl_p':     [ve][f] pos. hel. of asymmetry calcuated through slopes 
                              of pre and post middle time bin. Slope method only 
                              for >= 5 time bins, corresponds to >= 3 RF on delays
              'sl_n':     [ve][f] negative helicity.
              'sl_c':     [ve][f] combined helicity.
          """
          
          # check rebin factor
          if type(rebin) not in (int,np.int64) or rebin < 1:
              raise RuntimeError('Rebinning factor must be int >= 1.')
          
          # check for additonal options (1F)
          if omit != '':
              further_options = list(map(str.strip,omit.split(' ')))
          else:
              further_options = list(map(str.strip,option.split(' ')[1:]))
          option = option.split(' ')[0].strip()
          
          # Option reduction
          option = option.lower()
          if option == ""                                     : pass
          elif option in ['+','up','u','p','pos','positive']  : option = 'positive'
          elif option in ['-','down','d','n','neg','negative']: option = 'negative'
          elif option in ["c","com","combined"]               : option = "combined"
          elif option in ["h","hel","helicity"]               : option = 'helicity'
          elif option in ["r","raw"]                          : option = 'raw'
          elif option in ['adif','ad','adiff']                : option = 'alpha_diffusion'
          elif option in ['atag','at']                        : option = 'alpha_tagged'
          else:
              raise RuntimeError("Option not recognized.")
          
          # get data
          if hist_select != '':
              
              # split into parts
              hist_select_temp = []
              for histname in hist_select.split(','):
                  hist_select_temp.extend(histname.split(';'))
              hist_select = [h.strip() for h in hist_select_temp]
              
              # check for user error
              if len(hist_select) < 4:
                  raise RuntimeError('hist_select must be a string of at least '+\
                          'four [,]-seperated or [;]-seperated histogram names')
              
              # get data
              d = [self.hist[h].data for h in hist_select]
              d_all = d
              
          # get default data
          else:
              d = self._get_area_data() # 1+ 2+ 1- 2-
              d_all = d
              
          # get alpha diffusion data
          if self.mode == '2h':
              d_alpha = d[4:]
              d = d[:4]
          
          # SLR -----------------------------------------------------------------
          if self.mode in ["20",'2h']:
              
              # calculate background
              n_prebeam = int(self.ppg['prebeam'].mean)
              bkgd = np.sum(np.asarray(d_all)[:,:n_prebeam],axis=1)
              bkgd_err = np.sqrt(bkgd)/n_prebeam
              bkgd /= n_prebeam
              
              # subtract background from counts, remove negative count values,
              # delete prebeam entries
              for i in range(len(d)):
                  d[i] = d[i]-bkgd[i]
                  d[i][d[i]<0] = 0.
                  d[i] = np.delete(d[i],np.arange(n_prebeam))
  
              # do alpha background subtractions
              if self.mode == '2h':    
                  for i in range(len(d_alpha)):
                      d_alpha[i] = d_alpha[i]-bkgd[i+len(d)]
                      d_alpha[i][d_alpha[i]<0] = 0.
                      d_alpha[i] = np.delete(d_alpha[i],np.arange(n_prebeam))
                  
              # get helicity data
              if option != 'combined':
                  h = np.array(self._get_asym_hel(d))
                  
              # rebin time
              time = (np.arange(len(d[0]))+0.5)*self.ppg['dwelltime'].mean/1000
              if rebin > 1:
                  len_t = len(time)
                  new_time = (np.average(time[i:i+rebin-1]) for i in np.arange(0,len_t,rebin))
                  time = np.fromiter(new_time,dtype=float,count=int(len_t/rebin))
  
              # mode switching
              if option == 'positive': # ---------------------------------------
                  return np.vstack([time,self._rebin(h[0],rebin)])
                  
              elif option == 'negative': # -------------------------------------
                  return np.vstack([time,self._rebin(h[1],rebin)])
  
              elif option == 'helicity': # -------------------------------------
                  out = bdict()
                  out['p'] = self._rebin(h[0],rebin)
                  out['n'] = self._rebin(h[1],rebin)
                  out['time_s'] = time
                  return out
  
              elif option == 'combined': # -------------------------------------
                  c = np.array(self._get_asym_comb(d))
                  return np.vstack([time,self._rebin(c,rebin)])
                  
              elif option == 'alpha_diffusion': # ------------------------------
                  try:
                      asym = self._get_asym_alpha(d_alpha,d)
                  except UnboundLocalError as err:
                      if self.mode != '2h':
                          raise RuntimeError('Run is not in 2h mode.')
                  return np.vstack([time,self._rebin(asym,rebin)])
              
              elif option == 'alpha_tagged': # ---------------------------------
                  try:
                      asym = self._get_asym_alpha_tag(d_alpha,d)  
                  except UnboundLocalError as err:
                      if self.mode != '2h':
                          raise RuntimeError('Run is not in 2h mode.')
                      else:
                          raise err
                  
                  out = bdict()
                  out['p_wiA'] = self._rebin(asym[0][0],rebin)
                  out['n_wiA'] = self._rebin(asym[0][1],rebin)
                  out['p_noA'] = self._rebin(asym[1][0],rebin)
                  out['n_noA'] = self._rebin(asym[1][1],rebin)
                  out['p_noT'] = self._rebin(asym[2][0],rebin)
                  out['n_noT'] = self._rebin(asym[2][1],rebin)
                  out['c_wiA'] = self._rebin(asym[3],rebin)
                  out['c_noA'] = self._rebin(asym[4],rebin)
                  out['c_noT'] = self._rebin(asym[5],rebin)
                  out['time_s'] = time
                  
                  return out
              
              else:
                  c = np.array(self._get_asym_comb(d))
                  
                  out = bdict()
                  out['p'] = self._rebin(h[0],rebin)
                  out['n'] = self._rebin(h[1],rebin)
                  out['c'] = self._rebin(c,rebin)  
                  out['time_s'] = time
                  return out
          
          # 1F ------------------------------------------------------------------
          elif self.mode in ['1f','1n']:
              
              # get xaxis label and data key
              if self.mode == '1f':
                  xlabel = 'Frequency'
                  xlab = 'freq'
              elif self.mode == '1n':
                  xlabel = 'Rb Cell mV set'
                  xlab = 'mV'
              
              # get bins to kill
              bin_ranges_str = further_options 
              bin_ranges = []
              for b in bin_ranges_str:
                  if not '-' in b:
                      bin_ranges.append(int(b))
                  else:
                      one = int(b.split('-')[0])
                      two = int(b.split('-')[1])
                      bin_ranges.extend(np.arange(one,two+1))
              
              # kill bins
              for i in range(len(d)):
  
                  # get good bin range
                  if len(bin_ranges) > 0:
                      bin_ranges = np.array(bin_ranges)
                      idx = (bin_ranges>=0)*(bin_ranges<len(d[i]))
                      bin_ranges = bin_ranges[idx]
  
                  # kill
                  d[i][bin_ranges] = 0.
              
              # get frequency
              freq = self.hist[xlabel].data
              
              # mode switching
              if option =='raw':
                  a = self._get_asym_hel(d)
                  out = bdict()
                  out['p'] = np.array(a[0])
                  out['n'] = np.array(a[1])
                  out[xlab] = np.array(freq)
                  return out 
              else:
                  freq,d = self._get_1f_sum_scans(d,freq)
                                         
              # rebin frequency
              if rebin>1:
                  len_f = len(freq)
                  newf = (np.average(freq[i:i+rebin-1]) for i in np.arange(0,len_f,rebin))
                  freq = np.fromiter(newf,dtype=float,count=int(np.ceil(len_f/rebin)))
                                         
              # swtich between remaining modes
              if option == 'helicity':
                  a = self._get_asym_hel(d)
                  out = bdict()
                  out['p'] = self._rebin(a[0],rebin)
                  out['n'] = self._rebin(a[1],rebin)
                  out[xlab] = np.array(freq)
                  return out
              
              elif option == 'positive':
                  a = self._get_asym_hel(d)
                  return np.vstack([freq,self._rebin(a[0],rebin)])
              
              elif option == 'negative':
                  a = self._get_asym_hel(d)
                  return np.vstack([freq,self._rebin(a[1],rebin)])
              
              elif option in ['combined']:
                  a = self._get_asym_comb(d)
                  return np.vstack([freq,self._rebin(a,rebin)])
              else:
                  ah = self._get_asym_hel(d)
                  ac = self._get_asym_comb(d)
                  
                  out = bdict()
                  out['p'] = self._rebin(ah[0],rebin)
                  out['n'] = self._rebin(ah[1],rebin)
                  out['c'] = self._rebin(ac,rebin)  
                  out[xlab] = np.array(freq)
                  return out
              
          # 2E ------------------------------------------------------------------
          elif self.mode in ['2e']:
              return self._get_2e_asym()
          
          # unknown entry -------------------------------------------------------
          else:
              print("Unknown run type.")
              return