code: def propagate_lithology_cols(self):
          
          cols = ['lithologies', 'geologic_types', 'geologic_classes']
          #for table in ['specimens', 'samples']:
              # convert "Not Specified" to blank
              #self.tables[table].df.replace("^[Nn]ot [Ss]pecified", '',
              #                              regex=True, inplace=True)
          self.propagate_cols(cols, 'samples', 'sites')
          cols = ['lithologies', 'geologic_types', 'geologic_classes']
          self.propagate_cols(cols, 'specimens', 'samples')
          # if sites table is missing any values,
          # go ahead and propagate values UP as well
          if 'sites' not in self.tables:
              return
          for col in cols:
              if col not in self.tables['sites'].df.columns:
                  self.tables['sites'].df[col] = None
          if not all(self.tables['sites'].df[cols].values.ravel()):
              print('-I- Propagating values up from samples to sites...')
              self.propagate_cols_up(cols, 'sites', 'samples')
docs: Propagate any data from lithologies, geologic_types, or geologic_classes
          from the sites table to the samples and specimens table.
          In the samples/specimens tables, null or "Not Specified" values
          will be overwritten based on the data from their parent site.