def get_age_levels(self):
        """
        Method to add a "level" column to the ages table.
        Finds the lowest filled in level (i.e., specimen, sample, etc.)
        for that particular row.
        I.e., a row with both site and sample name filled in is considered
        a sample-level age.

        Returns
        ---------
        self.tables['ages'] : MagicDataFrame
            updated ages table
        """
        def get_level(ser, levels=('specimen', 'sample', 'site', 'location')):
            for level in levels:
                if pd.notnull(ser[level]):
                    if len(ser[level]):  # guard against empty strings
                        return level
            return
        # get available levels in age table
        possible_levels = ['specimen', 'sample', 'site', 'location']
        levels = [level for level in possible_levels if level in self.tables['ages'].df.columns]
        # find level for each age row
        age_levels = self.tables['ages'].df.apply(get_level, axis=1, args=[levels])
        if any(age_levels):
            self.tables['ages'].df.loc[:, 'level'] = age_levels
        return self.tables['ages']
Method to add a "level" column to the ages table.
        Finds the lowest filled in level (i.e., specimen, sample, etc.)
        for that particular row.
        I.e., a row with both site and sample name filled in is considered
        a sample-level age.

        Returns
        ---------
        self.tables['ages'] : MagicDataFrame
            updated ages table