docs: def absorptionCoefficient_Doppler(Components=None,SourceTables=None,partitionFunction=PYTIPS,
                                    Environment=None,OmegaRange=None,OmegaStep=None,OmegaWing=None,
                                    IntensityThreshold=DefaultIntensityThreshold,
                                    OmegaWingHW=DefaultOmegaWingHW,
                                    ParameterBindings=DefaultParameterBindings,
                                    EnvironmentDependencyBindings=DefaultEnvironmentDependencyBindings,
                                    GammaL='dummy', HITRAN_units=True, LineShift=True,
                                    File=None, Format=None, OmegaGrid=None,
                                    WavenumberRange=None,WavenumberStep=None,WavenumberWing=None,
                                    WavenumberWingHW=None,WavenumberGrid=None):   
      """
      INPUT PARAMETERS: 
          Components:  list of tuples [(M,I,D)], where
                          M - HITRAN molecule number,
                          I - HITRAN isotopologue number,
                          D - abundance (optional)
          SourceTables:  list of tables from which to calculate cross-section   (optional)
          partitionFunction:  pointer to partition function (default is PYTIPS) (optional)
          Environment:  dictionary containing thermodynamic parameters.
                          'p' - pressure in atmospheres,
                          'T' - temperature in Kelvin
                          Default={'p':1.,'T':296.}
          WavenumberRange:  wavenumber range to consider.
          WavenumberStep:   wavenumber step to consider. 
          WavenumberWing:   absolute wing for calculating a lineshape (in cm-1) 
          WavenumberWingHW:  relative wing for calculating a lineshape (in halfwidths)
          IntensityThreshold:  threshold for intensities
          GammaL:  specifies broadening parameter ('gamma_air' or 'gamma_self')
          HITRAN_units:  use cm2/molecule (True) or cm-1 (False) for absorption coefficient
          File:   write output to file (if specified)
          Format:  c-format of file output (accounts for significant digits in WavenumberStep)
      OUTPUT PARAMETERS: 
          Wavenum: wavenumber grid with respect to parameters OmegaRange and OmegaStep
          Xsect: absorption coefficient calculated on the grid
      ---
      DESCRIPTION:
          Calculate absorption coefficient using Doppler (Gauss) profile.
          Absorption coefficient is calculated at arbitrary temperature and pressure.
          User can vary a wide range of parameters to control a process of calculation.
          The choise of these parameters depends on properties of a particular linelist.
          Default values are a sort of guess which give a decent precision (on average) 
          for a reasonable amount of cpu time. To increase calculation accuracy,
          user should use a trial and error method.
      ---
      EXAMPLE OF USAGE:
          nu,coef = absorptionCoefficient_Doppler(((2,1),),'co2',WavenumberStep=0.01,
                                                HITRAN_units=False,GammaL='gamma_self')
      ---
      """
  
      if WavenumberRange:  OmegaRange=WavenumberRange
      if WavenumberStep:   OmegaStep=WavenumberStep
      if WavenumberWing:   OmegaWing=WavenumberWing
      if WavenumberWingHW: OmegaWingHW=WavenumberWingHW
      if WavenumberGrid:   OmegaGrid=WavenumberGrid
      
      # "bug" with 1-element list
      Components = listOfTuples(Components)
      SourceTables = listOfTuples(SourceTables)
      
      # determine final input values
      Components,SourceTables,Environment,OmegaRange,OmegaStep,OmegaWing,\
      IntensityThreshold,Format = \
         getDefaultValuesForXsect(Components,SourceTables,Environment,OmegaRange,
                                  OmegaStep,OmegaWing,IntensityThreshold,Format)
      # special for Doppler case: set OmegaStep to a smaller value
      if not OmegaStep: OmegaStep = 0.001
                  
      # warn user about too large omega step
      if OmegaStep>0.005: warn('Big wavenumber step: possible accuracy decline')
  
      # get uniform linespace for cross-section
      #number_of_points = (OmegaRange[1]-OmegaRange[0])/OmegaStep + 1
      #Omegas = linspace(OmegaRange[0],OmegaRange[1],number_of_points)
      if OmegaGrid is not None:
          Omegas = npsort(OmegaGrid)
      else:
          #Omegas = arange(OmegaRange[0],OmegaRange[1],OmegaStep)
          Omegas = arange_(OmegaRange[0],OmegaRange[1],OmegaStep) # fix
      number_of_points = len(Omegas)
      Xsect = zeros(number_of_points)
         
      # reference temperature and pressure
      Tref = __FloatType__(296.) # K
      pref = __FloatType__(1.) # atm
      
      # actual temperature and pressure
      T = Environment['T'] # K
      p = Environment['p'] # atm
         
      # create dictionary from Components
      ABUNDANCES = {}
      NATURAL_ABUNDANCES = {}
      for Component in Components:
          M = Component[0]
          I = Component[1]
          if len(Component) >= 3:
              ni = Component[2]
          else:
              try:
                  ni = ISO[(M,I)][ISO_INDEX['abundance']]
              except KeyError:
                  raise Exception('cannot find component M,I = %d,%d.' % (M,I))
          ABUNDANCES[(M,I)] = ni
          NATURAL_ABUNDANCES[(M,I)] = ISO[(M,I)][ISO_INDEX['abundance']]
          
      # precalculation of volume concentration
      if HITRAN_units:
          factor = __FloatType__(1.0)
      else:
          factor = volumeConcentration(p,T) 
          
      # SourceTables contain multiple tables
      for TableName in SourceTables:
  
          # get line centers
          nline = LOCAL_TABLE_CACHE[TableName]['header']['number_of_rows']
          
          # loop through line centers (single stream)
          for RowID in range(nline):
              
              # get ftbasic line parameters (lower level)
              LineCenterDB = LOCAL_TABLE_CACHE[TableName]['data']['nu'][RowID]
              LineIntensityDB = LOCAL_TABLE_CACHE[TableName]['data']['sw'][RowID]
              LowerStateEnergyDB = LOCAL_TABLE_CACHE[TableName]['data']['elower'][RowID]
              MoleculeNumberDB = LOCAL_TABLE_CACHE[TableName]['data']['molec_id'][RowID]
              IsoNumberDB = LOCAL_TABLE_CACHE[TableName]['data']['local_iso_id'][RowID]
              if LineShift:
                  Shift0DB = LOCAL_TABLE_CACHE[TableName]['data']['delta_air'][RowID]
              else:
                  Shift0DB = 0
              
              # filter by molecule and isotopologue
              if (MoleculeNumberDB,IsoNumberDB) not in ABUNDANCES: continue
              
              # partition functions for T and Tref
              # TODO: optimize
              SigmaT = partitionFunction(MoleculeNumberDB,IsoNumberDB,T)
              SigmaTref = partitionFunction(MoleculeNumberDB,IsoNumberDB,Tref)
              
              # get all environment dependences from voigt parameters
              
              #   intensity
              LineIntensity = EnvironmentDependency_Intensity(LineIntensityDB,T,Tref,SigmaT,SigmaTref,
                                                              LowerStateEnergyDB,LineCenterDB)
              
              #   FILTER by LineIntensity: compare it with IntencityThreshold
              # TODO: apply wing narrowing instead of filtering, this would be more appropriate
              if LineIntensity < IntensityThreshold: continue
              
              #   doppler broadening coefficient (GammaD)
              #GammaDDB = cSqrtLn2*LineCenterDB/cc*sqrt(2*cBolts*T/molecularMass(MoleculeNumberDB,IsoNumberDB))
              #GammaD = EnvironmentDependency_GammaD(GammaDDB,T,Tref)
              #print(GammaD)
  
              cMassMol = 1.66053873e-27
              #cSqrt2Ln2 = 1.1774100225
              fSqrtMass = sqrt(molecularMass(MoleculeNumberDB,IsoNumberDB))
              #fSqrtMass = sqrt(32831.2508809)
              cc_ = 2.99792458e8
              cBolts_ = 1.3806503e-23
              #cBolts_ = 1.3806488E-23
              GammaD = (cSqrt2Ln2/cc_)*sqrt(cBolts_/cMassMol)*sqrt(T) * LineCenterDB/fSqrtMass
              
              #GammaD = 4.30140e-7*LineCenterDB*sqrt(T/molecularMass(MoleculeNumberDB,IsoNumberDB))
  
              #cc_ = 2.99792458e8 # 2.99792458e10 # 2.99792458e8
              #cBolts_ = 1.3806503e-23 #1.3806488E-16 # 1.380648813E-16 # 1.3806503e-23 # 1.3806488E-23
              #GammaD = sqrt(log(2))*LineCenterDB*sqrt(2*cBolts_*T/(cMassMol*molecularMass(MoleculeNumberDB,IsoNumberDB)*cc_**2))
              #print(GammaD)
              
              #   get final wing of the line according to GammaD, OmegaWingHW and OmegaWing
              # XXX min or max?
              OmegaWingF = max(OmegaWing,OmegaWingHW*GammaD)
  
              #   shift coefficient
              Shift0 = Shift0DB*p/pref
  
              # XXX other parameter (such as Delta0, Delta2, anuVC etc.) will be included in HTP version
              
              #PROFILE_VOIGT(sg0,GamD,Gam0,sg)
              #      sg0           : Unperturbed line position in cm-1 (Input).
              #      GamD          : Doppler HWHM in cm-1 (Input)
              #      Gam0          : Speed-averaged line-width in cm-1 (Input).
              #      sg            : Current WaveNumber of the Computation in cm-1 (Input).
                                                
              # XXX time?
              BoundIndexLower = bisect(Omegas,LineCenterDB-OmegaWingF)
              BoundIndexUpper = bisect(Omegas,LineCenterDB+OmegaWingF)
              lineshape_vals = PROFILE_DOPPLER(LineCenterDB+Shift0,GammaD,Omegas[BoundIndexLower:BoundIndexUpper])
              #lineshape_vals = PROFILE_VOIGT(LineCenterDB,GammaD,cZero,Omegas[BoundIndexLower:BoundIndexUpper])[0]
              #Xsect[BoundIndexLower:BoundIndexUpper] += lineshape_vals # DEBUG
              Xsect[BoundIndexLower:BoundIndexUpper] += factor / NATURAL_ABUNDANCES[(MoleculeNumberDB,IsoNumberDB)] * \
                                                        ABUNDANCES[(MoleculeNumberDB,IsoNumberDB)] * \
                                                        LineIntensity * lineshape_vals
  
      if File: save_to_file(File,Format,Omegas,Xsect)
      return Omegas,Xsect