docs: def generate_usgs_avg_daily_flows_opt(self,
                                            reach_id_gage_id_file,
                                            start_datetime,
                                            end_datetime,
                                            out_streamflow_file,
                                            out_stream_id_file):
          """
          Generate daily streamflow file and stream id file required for
          calibration or for substituting flows based on USGS gage ids
          associated with stream ids.
  
          Parameters
          ----------
          reach_id_gage_id_file: str
              Path to reach_id_gage_id file.
          start_datetime: datetime
              A datetime object with the start date to download data.
          end_datetime: datetime
              A datetime object with the end date to download data.
          out_streamflow_file: str
              The path to output the streamflow file for RAPID.
          out_stream_id_file: str
              The path to output the stream ID file associated with the
              streamflow file for RAPID.
  
  
          Example *reach_id_gage_id_file*::
  
              COMID, USGS_GAGE_ID
              2000, 503944
              ...
  
          .. warning:: Overuse will get you blocked from downloading data from
                       USGS.
  
          .. warning:: This code does not clean the data in any way. Thus, you
                       are likely to run into issues if you simply use the raw
                       data.
  
          .. warning:: The code skips gages that do not have data
                       for the entire time period.
  
  
          Simple Example:
  
          .. code:: python
  
              import datetime
              from os.path import join
              from RAPIDpy import RAPID
  
              main_path = "/home/username/data"
  
              rapid_manager = RAPID()
              rapid_manager.generate_usgs_avg_daily_flows_opt(
                  reach_id_gage_id_file=join(main_path, "usgsgage_id_comid.csv"),
                  start_datetime=datetime.datetime(2000,1,1),
                  end_datetime=datetime.datetime(2014,12,31),
                  out_streamflow_file=join(main_path,"streamflow_2000_2014.csv"),
                  out_stream_id_file=join(main_path,"streamid_2000_2014.csv")
              )
  
  
          Complex Example:
  
          .. code:: python
  
              import datetime
              from os.path import join
              from RAPIDpy import RAPID
  
              main_path = "/home/username/data"
  
              rapid_manager = RAPID(
                  rapid_executable_location='~/work/rapid/run/rapid'
                  use_all_processors=True,
                  ZS_TauR=24*3600,
                  ZS_dtR=15*60,
                  ZS_TauM=365*24*3600,
                  ZS_dtM=24*3600
              )
  
              rapid_manager.update_parameters(
                  rapid_connect_file='../rapid-io/input/rapid_connect.csv',
                  Vlat_file='../rapid-io/input/m3_riv.nc',
                  riv_bas_id_file='../rapid-io/input/riv_bas_id.csv',
                  k_file='../rapid-io/input/k.csv',
                  x_file='../rapid-io/input/x.csv',
                  Qout_file='../rapid-io/output/Qout.nc',
              )
  
              rapid_manager.update_reach_number_data()
              rapid_manager.update_simulation_runtime()
              rapid_manager.generate_usgs_avg_daily_flows_opt(
                  reach_id_gage_id_file=join(main_path, "usgsgage_id_comid.csv"),
                  start_datetime=datetime.datetime(2000,1,1),
                  end_datetime=datetime.datetime(2014,12,31),
                  out_streamflow_file=join(main_path,"streamflow_2000_2014.csv"),
                  out_stream_id_file=join(main_path,"streamid_2000_2014.csv")
                  )
              rapid_manager.run()
  
          """
          log("Generating avg streamflow file and stream id file "
              "required for calibration ...",
              "INFO")
          log("Generating avg streamflow file and stream id file "
              "required for calibration ...",
              "INFO")
          reach_id_gage_id_list = csv_to_list(reach_id_gage_id_file)
          gage_data_matrix = []
          valid_comid_list = []
  
          # add extra day as it includes the start date
          # (e.g. 7-5 is 2 days, but have data for 5,6,7, so +1)
          num_days_needed = (end_datetime-start_datetime).days + 1
  
          gage_id_list = []
          for row in reach_id_gage_id_list[1:]:
              station_id = row[1]
              if len(row[1]) == 7:
                  station_id = '0' + row[1]
              gage_id_list.append(station_id)
  
          num_gage_id_list = np.array(gage_id_list, dtype=np.int32)
          log("Querying Server for Data ...",
              "INFO")
  
          query_params = {
                          'format': 'json',
                          'sites': ",".join(gage_id_list),
                          'startDT': start_datetime.strftime("%Y-%m-%d"),
                          'endDT': end_datetime.strftime("%Y-%m-%d"),
                          'parameterCd': '00060',  # streamflow
                          'statCd': '00003'  # average
                         }
          response = get("http://waterservices.usgs.gov/nwis/dv",
                         params=query_params)
  
          if not response.ok:
              log("USGS query error ...",
                  "WARNING")
              return
  
          requested_data = None
          try:
              requested_data = response.json()['value']['timeSeries']
          except IndexError:
              pass
  
          if requested_data is not None:
              for time_series in enumerate(requested_data):
                  usgs_station_full_name = time_series[1]['name']
                  usgs_station_id = usgs_station_full_name.split(":")[1]
                  gage_data = []
                  for time_step in time_series[1]['values'][0]['value']:
                      local_datetime = parse(time_step['dateTime'])
                      if local_datetime > end_datetime:
                          break
  
                      if local_datetime >= start_datetime:
                          if not time_step['value']:
                              log("MISSING DATA for USGS Station {0} {1} {2}"
                                  .format(usgs_station_id,
                                          local_datetime,
                                          time_step['value']),
                                  "WARNING")
                          gage_data.append(
                              float(time_step['value']) / 35.3146667)
  
                  try:
                      # get where streamids associated with USGS station ID
                      streamid_index = \
                          np.where(num_gage_id_list ==
                                   int(float(usgs_station_id)))[0][0]+1
                  except (IndexError, ValueError):
                      log("USGS Station {0} not found in list ..."
                          .format(usgs_station_id),
                          "WARNING")
                      raise
  
                  if len(gage_data) == num_days_needed:
                      gage_data_matrix.append(gage_data)
                      valid_comid_list.append(
                          reach_id_gage_id_list[streamid_index][0])
                  else:
                      log("StreamID {0} USGS Station {1} MISSING {2} "
                          "DATA VALUES".format(
                              reach_id_gage_id_list[streamid_index][0],
                              usgs_station_id,
                              num_days_needed-len(gage_data)),
                          "WARNING")
  
          if gage_data_matrix and valid_comid_list:
              log("Writing Output ...",
                  "INFO")
              np_array = np.array(gage_data_matrix).transpose()
              with open_csv(out_streamflow_file, 'w') as gage_data:
                  wgd = csvwriter(gage_data)
                  for row in np_array:
                      wgd.writerow(row)
  
              with open_csv(out_stream_id_file, 'w') as comid_data:
                  wcd = csvwriter(comid_data)
                  for row in valid_comid_list:
                      wcd.writerow([int(float(row))])
  
              # set parameters for RAPID run
              self.IS_obs_tot = len(valid_comid_list)
              self.obs_tot_id_file = out_stream_id_file
              self.Qobs_file = out_streamflow_file
              self.IS_obs_use = len(valid_comid_list)
              self.obs_use_id_file = out_stream_id_file
          else:
              log("No valid data returned ...",
                  "WARNING")