<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def handle_extra_source(self, source_df, sim_params):
 """ Extra sources always have a sid column. We expand the given data (by forward filling) to the full range of the simulation dates, so that lookup is fast during simulation. """

        if source_df is None:
            return

        # Normalize all the dates in the df
        source_df.index = source_df.index.normalize()

        # source_df's sid column can either consist of assets we know about
        # (such as sid(24)) or of assets we don't know about (such as
        # palladium).
        #
        # In both cases, we break up the dataframe into individual dfs
        # that only contain a single asset's information.  ie, if source_df
        # has data for PALLADIUM and GOLD, we split source_df into two
        # dataframes, one for each. (same applies if source_df has data for
        # AAPL and IBM).
        #
        # We then take each child df and reindex it to the simulation's date
        # range by forward-filling missing values. this makes reads simpler.
        #
        # Finally, we store the data. For each column, we store a mapping in
        # self.augmented_sources_map from the column to a dictionary of
        # asset -> df.  In other words,
        # self.augmented_sources_map['days_to_cover']['AAPL'] gives us the df
        # holding that data.
        source_date_index = self.trading_calendar.sessions_in_range(
            sim_params.start_session,
            sim_params.end_session
        )

        # Break the source_df up into one dataframe per sid.  This lets
        # us (more easily) calculate accurate start/end dates for each sid,
        # de-dup data, and expand the data to fit the backtest start/end date.
        grouped_by_sid = source_df.groupby(["sid"])
        group_names = grouped_by_sid.groups.keys()
        group_dict = {}
        for group_name in group_names:
            group_dict[group_name] = grouped_by_sid.get_group(group_name)

        # This will be the dataframe which we query to get fetcher assets at
        # any given time. Get's overwritten every time there's a new fetcher
        # call
        extra_source_df = pd.DataFrame()

        for identifier, df in iteritems(group_dict):
            # Since we know this df only contains a single sid, we can safely
            # de-dupe by the index (dt). If minute granularity, will take the
            # last data point on any given day
            df = df.groupby(level=0).last()

            # Reindex the dataframe based on the backtest start/end date.
            # This makes reads easier during the backtest.
            df = self._reindex_extra_source(df, source_date_index)

            for col_name in df.columns.difference(['sid']):
                if col_name not in self._augmented_sources_map:
                    self._augmented_sources_map[col_name] = {}

                self._augmented_sources_map[col_name][identifier] = df

            # Append to extra_source_df the reindexed dataframe for the single
            # sid
            extra_source_df = extra_source_df.append(df)

        self._extra_source_df = extra_source_df