nodes: 0, module; 1, function_definition; 2, function_name:get_last_data_per_qtr; 3, parameters; 4, block; 5, identifier:self; 6, identifier:assets_with_data; 7, identifier:columns; 8, identifier:dates; 9, identifier:data_query_cutoff_times; 10, expression_statement; 11, comment:# Get a DataFrame indexed by date with a MultiIndex of columns of; 12, comment:# [self.estimates.columns, normalized_quarters, sid], where each cell; 13, comment:# contains the latest data for that day.; 14, expression_statement; 15, expression_statement; 16, comment:# Forward fill values for each quarter/sid/dataset column.; 17, expression_statement; 18, comment:# Stack quarter and sid into the index.; 19, expression_statement; 20, comment:# Set date index name for ease of reference; 21, expression_statement; 22, expression_statement; 23, expression_statement; 24, return_statement; 25, comment:"""
          Determine the last piece of information we know for each column on each
          date in the index for each sid and quarter.
  
          Parameters
          ----------
          assets_with_data : pd.Index
              Index of all assets that appear in the raw data given to the
              loader.
          columns : iterable of BoundColumn
              The columns that need to be loaded from the raw data.
          data_query_cutoff_times : pd.DatetimeIndex
              The calendar of dates for which data should be loaded.
  
          Returns
          -------
          stacked_last_per_qtr : pd.DataFrame
              A DataFrame indexed by [dates, sid, normalized_quarters] that has
              the latest information for each row of the index, sorted by event
              date.
          last_per_qtr : pd.DataFrame
              A DataFrame with columns that are a MultiIndex of [
              self.estimates.columns, normalized_quarters, sid].
          """; 26, assignment; 27, assignment; 28, call; 29, assignment; 30, call; 31, assignment; 32, assignment; 33, expression_list; 34, identifier:last_per_qtr; 35, call; 36, attribute; 37, identifier:dates; 38, identifier:ffill_across_cols; 39, argument_list; 40, identifier:stacked_last_per_qtr; 41, call; 42, attribute; 43, argument_list; 44, identifier:stacked_last_per_qtr; 45, call; 46, subscript; 47, call; 48, identifier:last_per_qtr; 49, identifier:stacked_last_per_qtr; 50, identifier:last_in_date_group; 51, argument_list; 52, identifier:last_per_qtr; 53, identifier:index; 54, identifier:last_per_qtr; 55, identifier:columns; 56, attribute; 57, attribute; 58, argument_list; 59, attribute; 60, identifier:set_names; 61, identifier:SIMULATION_DATES; 62, keyword_argument; 63, keyword_argument; 64, attribute; 65, argument_list; 66, identifier:stacked_last_per_qtr; 67, identifier:EVENT_DATE_FIELD_NAME; 68, attribute; 69, argument_list; 70, attribute; 71, identifier:data_query_cutoff_times; 72, identifier:assets_with_data; 73, keyword_argument; 74, keyword_argument; 75, identifier:self; 76, identifier:name_map; 77, identifier:last_per_qtr; 78, identifier:stack; 79, list; 80, identifier:stacked_last_per_qtr; 81, identifier:index; 82, identifier:level; 83, integer:0; 84, identifier:inplace; 85, True; 86, identifier:stacked_last_per_qtr; 87, identifier:sort_values; 88, identifier:EVENT_DATE_FIELD_NAME; 89, identifier:pd; 90, identifier:to_datetime; 91, subscript; 92, identifier:self; 93, identifier:estimates; 94, identifier:reindex; 95, True; 96, identifier:extra_groupers; 97, list; 98, identifier:SID_FIELD_NAME; 99, identifier:NORMALIZED_QUARTERS; 100, identifier:stacked_last_per_qtr; 101, identifier:EVENT_DATE_FIELD_NAME; 102, identifier:NORMALIZED_QUARTERS
code: def get_last_data_per_qtr(self,
                                assets_with_data,
                                columns,
                                dates,
                                data_query_cutoff_times):
          """
          Determine the last piece of information we know for each column on each
          date in the index for each sid and quarter.
  
          Parameters
          ----------
          assets_with_data : pd.Index
              Index of all assets that appear in the raw data given to the
              loader.
          columns : iterable of BoundColumn
              The columns that need to be loaded from the raw data.
          data_query_cutoff_times : pd.DatetimeIndex
              The calendar of dates for which data should be loaded.
  
          Returns
          -------
          stacked_last_per_qtr : pd.DataFrame
              A DataFrame indexed by [dates, sid, normalized_quarters] that has
              the latest information for each row of the index, sorted by event
              date.
          last_per_qtr : pd.DataFrame
              A DataFrame with columns that are a MultiIndex of [
              self.estimates.columns, normalized_quarters, sid].
          """
          # Get a DataFrame indexed by date with a MultiIndex of columns of
          # [self.estimates.columns, normalized_quarters, sid], where each cell
          # contains the latest data for that day.
          last_per_qtr = last_in_date_group(
              self.estimates,
              data_query_cutoff_times,
              assets_with_data,
              reindex=True,
              extra_groupers=[NORMALIZED_QUARTERS],
          )
          last_per_qtr.index = dates
          # Forward fill values for each quarter/sid/dataset column.
          ffill_across_cols(last_per_qtr, columns, self.name_map)
          # Stack quarter and sid into the index.
          stacked_last_per_qtr = last_per_qtr.stack(
              [SID_FIELD_NAME, NORMALIZED_QUARTERS],
          )
          # Set date index name for ease of reference
          stacked_last_per_qtr.index.set_names(
              SIMULATION_DATES,
              level=0,
              inplace=True,
          )
          stacked_last_per_qtr = stacked_last_per_qtr.sort_values(
              EVENT_DATE_FIELD_NAME,
          )
          stacked_last_per_qtr[EVENT_DATE_FIELD_NAME] = pd.to_datetime(
              stacked_last_per_qtr[EVENT_DATE_FIELD_NAME]
          )
          return last_per_qtr, stacked_last_per_qtr