def locate_data_source(self, data_sources, column_name=DATA_SOURCE_COLNAME,<EOL>source_key=None, extra_vars=None):
if not data_sources:<EOL><INDENT>return None<EOL><DEDENT>if not source_key:<EOL><INDENT>try:<EOL><INDENT>source_key = getattr(self, column_name)<EOL><DEDENT>except AttributeError:<EOL><INDENT>reason = "<STR_LIT>""<STR_LIT>""<STR_LIT>".format(<EOL>attr=column_name, sources=DATA_SOURCES_SECTION)<EOL>raise AttributeError(reason)<EOL><DEDENT><DEDENT>try:<EOL><INDENT>regex = data_sources[source_key]<EOL><DEDENT>except KeyError:<EOL><INDENT>_LOGGER.debug(<EOL>"<STR_LIT>"<EOL>"<STR_LIT>".format(<EOL>self.name, source_key, column_name, data_sources.keys()))<EOL>return "<STR_LIT>"<EOL><DEDENT>try:<EOL><INDENT>temp_dict = self.__dict__.copy()<EOL>temp_dict.update(extra_vars or dict())<EOL>val = regex.format(**temp_dict)<EOL>if '<STR_LIT:*>' in val or '<STR_LIT:[>' in val:<EOL><INDENT>_LOGGER.debug("<STR_LIT>", val)<EOL>val_globbed = sorted(glob.glob(val))<EOL>if not val_globbed:<EOL><INDENT>_LOGGER.debug("<STR_LIT>", val)<EOL><DEDENT>else:<EOL><INDENT>val = "<STR_LIT:U+0020>".join(val_globbed)<EOL><DEDENT>_LOGGER.debug("<STR_LIT>", val)<EOL><DEDENT><DEDENT>except Exception as e:<EOL><INDENT>_LOGGER.error("<STR_LIT>".<EOL>format(str(type(e).__name__), str(e), regex))<EOL>return regex<EOL><DEDENT>return val<EOL>
Uses the template path provided in the project config section
"data_sources" to piece together an actual path by substituting
variables (encoded by "{variable}"") with sample attributes.

:param Mapping data_sources: mapping from key name (as a value in
    a cell of a tabular data structure) to, e.g., filepath
:param str column_name: Name of sample attribute
    (equivalently, sample sheet column) specifying a derived column.
:param str source_key: The key of the data_source,
    used to index into the project config data_sources section.
    By default, the source key will be taken as the value of
    the specified column (as a sample attribute).
    For cases where the sample doesn't have this attribute yet
    (e.g. in a merge table), you must specify the source key.
:param dict extra_vars: By default, this will look to
    populate the template location using attributes found in the
    current sample; however, you may also provide a dict of extra
    variables that can also be used for variable replacement.
    These extra variables are given a higher priority.
:return str: regex expansion of data source specified in configuration,
    with variable substitutions made
:raises ValueError: if argument to data_sources parameter is null/empty