# This file is part of versuchung.
#
# versuchung is free software: you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# versuchung is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# versuchung. If not, see <http://www.gnu.org/licenses/>.
from __future__ import print_function
import os
import logging
from versuchung.types import List
[docs]def search_experiment_results(experiment_type, directory, selector = None, follow_links=True):
"""In large experiment setups it is hard to keep track of all
result sets, which were produced. Therefore a search on the
"result set database" is implemented with this function.
:param experiment_type: The experiment class object you are looking for
:param directory: Which directory to search for (recursivly)
:param selector: function that gets an experiment_type instance and returns a bool
:rtype: a list of experiment_type objects
The selector can also be a :class:`dict` will be wrapped automatically with
:func:`search_selector_metadata`.
>>> search_experiment_results(MyExperiment, ".", lambda e: "home" in e.path)
List(MyExperiment, <MyExperiment object at 0xb74805ec>])
"""
# Name -> Path
experiment_map = {}
experiment_title = experiment_type.__name__
if selector == None:
selector = lambda x: True
if type(selector) == dict:
selector = search_selector_metadata(selector)
for root, dirs, files in os.walk(directory, followlinks=follow_links):
if "metadata" in files:
experiment_name = os.path.basename(root)
path = root
if experiment_name.startswith(experiment_title):
dataset = experiment_type(path)
if selector(dataset):
exp = experiment_type(path)
if exp.path not in [e.path for e in experiment_map.values()]:
experiment_map[experiment_name] = exp
return List(experiment_type, experiment_map.values())
[docs]def search_experiment(experiment_type, directory, selector = None):
"""Like :func:`search_experiment_results`, but returns only one
experiment result set. And fails if it is ambigious"""
exps = search_experiment_results(experiment_type, directory, selector)
if len(exps) != 1:
logging.error("search_experiment didn't exactly one instance of %s (%d found)", experiment_type, len(exps))
for exp in exps:
logging.error(" - %s", exp.path)
assert False
return exps[0]
[docs]def search_path_go_up_till(path, till):
"""Go up in the given path (which is of type string), until the
directory is called till"""
while path and path != "" and os.path.basename(path) != till:
path = os.path.dirname(path)
assert path
return path
if __name__ == '__main__':
import sys
from versuchung.experiment import Experiment
if len(sys.argv) != 4:
print("%s <experiment-type> <field> <data>" % sys.argv[0])
sys.exit(-1)
Experiment.__name__ = sys.argv[1]
for exp in search_experiment_results(Experiment, ".", {sys.argv[2]: sys.argv[3]}):
print(exp.path)