Prepare the solar position, irradiance, and weather inputs to
        the model.

        Parameters
        ----------
        times : None or DatetimeIndex, default None
            Times at which to evaluate the model. Can be None if
            attribute `times` is already set.
        weather : None or DataFrame, default None
            If ``None``, the weather attribute is used. If the weather
            attribute is also ``None`` assumes air temperature is 20 C, wind
            speed is 0 m/s and irradiation calculated from clear sky
            data. Column names must be ``'wind_speed'``, ``'temp_air'``,
            ``'dni'``, ``'ghi'``, ``'dhi'``. Do not pass incomplete irradiation
            data. Use method
            :py:meth:`~pvlib.modelchain.ModelChain.complete_irradiance`
            instead.

        Notes
        -----
        Assigns attributes: ``times``, ``solar_position``, ``airmass``,
        ``total_irrad``, `aoi`

def prepare_inputs(self, times=None, weather=None):
        """
        Prepare the solar position, irradiance, and weather inputs to
        the model.

        Parameters
        ----------
        times : None or DatetimeIndex, default None
            Times at which to evaluate the model. Can be None if
            attribute `times` is already set.
        weather : None or DataFrame, default None
            If ``None``, the weather attribute is used. If the weather
            attribute is also ``None`` assumes air temperature is 20 C, wind
            speed is 0 m/s and irradiation calculated from clear sky
            data. Column names must be ``'wind_speed'``, ``'temp_air'``,
            ``'dni'``, ``'ghi'``, ``'dhi'``. Do not pass incomplete irradiation
            data. Use method
            :py:meth:`~pvlib.modelchain.ModelChain.complete_irradiance`
            instead.

        Notes
        -----
        Assigns attributes: ``times``, ``solar_position``, ``airmass``,
        ``total_irrad``, `aoi`
        """
        if weather is not None:
            self.weather = weather
        if self.weather is None:
            self.weather = pd.DataFrame(index=times)

        if times is not None:
            self.times = times

        self.solar_position = self.location.get_solarposition(
            self.times, method=self.solar_position_method)

        self.airmass = self.location.get_airmass(
            solar_position=self.solar_position, model=self.airmass_model)

        if not any([x in ['ghi', 'dni', 'dhi'] for x in self.weather.columns]):
            self.weather[['ghi', 'dni', 'dhi']] = self.location.get_clearsky(
                self.solar_position.index, self.clearsky_model,
                solar_position=self.solar_position,
                airmass_absolute=self.airmass['airmass_absolute'])

        if not {'ghi', 'dni', 'dhi'} <= set(self.weather.columns):
            raise ValueError(
                "Uncompleted irradiance data set. Please check you input " +
                "data.\nData set needs to have 'dni', 'dhi' and 'ghi'.\n" +
                "Detected data: {0}".format(list(self.weather.columns)))

        # PVSystem.get_irradiance and SingleAxisTracker.get_irradiance
        # and PVSystem.get_aoi and SingleAxisTracker.get_aoi
        # have different method signatures. Use partial to handle
        # the differences.
        if isinstance(self.system, SingleAxisTracker):
            self.tracking = self.system.singleaxis(
                self.solar_position['apparent_zenith'],
                self.solar_position['azimuth'])
            self.tracking['surface_tilt'] = (
                self.tracking['surface_tilt']
                    .fillna(self.system.axis_tilt))
            self.tracking['surface_azimuth'] = (
                self.tracking['surface_azimuth']
                    .fillna(self.system.axis_azimuth))
            self.aoi = self.tracking['aoi']
            get_irradiance = partial(
                self.system.get_irradiance,
                self.tracking['surface_tilt'],
                self.tracking['surface_azimuth'],
                self.solar_position['apparent_zenith'],
                self.solar_position['azimuth'])
        else:
            self.aoi = self.system.get_aoi(
                self.solar_position['apparent_zenith'],
                self.solar_position['azimuth'])
            get_irradiance = partial(
                self.system.get_irradiance,
                self.solar_position['apparent_zenith'],
                self.solar_position['azimuth'])

        self.total_irrad = get_irradiance(
            self.weather['dni'],
            self.weather['ghi'],
            self.weather['dhi'],
            airmass=self.airmass['airmass_relative'],
            model=self.transposition_model)

        if self.weather.get('wind_speed') is None:
            self.weather['wind_speed'] = 0
        if self.weather.get('temp_air') is None:
            self.weather['temp_air'] = 20
        return self