Skip to content

Commit

Permalink
Merge pull request #97 from scidash/dash
Browse files Browse the repository at this point in the history
Dash
  • Loading branch information
rgerkin committed Apr 11, 2019
2 parents 256b4a7 + d9ef652 commit 335ae84
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 22 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
| [![RTFD](https://readthedocs.org/projects/sciunit/badge/?version=master)](http://sciunit.readthedocs.io/en/latest/?badge=master) | [![RTFD](https://readthedocs.org/projects/sciunit/badge/?version=dev)](http://sciunit.readthedocs.io/en/latest/?badge=dev) |
| [![Binder](https://mybinder.org/badge.svg)](https://mybinder.org/v2/gh/scidash/sciunit/master?filepath=docs%2Fchapter1.ipynb) | |
| [![Coveralls](https://coveralls.io/repos/github/scidash/sciunit/badge.svg?branch=master)](https://coveralls.io/github/scidash/sciunit?branch=master) | [![Coveralls](https://coveralls.io/repos/github/scidash/sciunit/badge.svg?branch=dev)](https://coveralls.io/github/scidash/sciunit?branch=dev) |
| [![Requirements](https://requires.io/github/scidash/sciunit/requirements.svg?branch=master)](https://requires.io/github/scidash/sciunit/requirements/?branch=master) | [![Requirements](https://requires.io/github/scidash/sciunit/requirements.svg?branch=dev)](https://requires.io/github/scidash/sciunit/requirements/?branch=dev) |
| [![Requirements](https://requires.io/github/scidash/sciunit/requirements.svg?branch=master)](https://requires.io/github/scidash/sciunit/requirements/?branch=master) | [![Requirements](https://requires.io/github/scidash/sciunit/requirements.svg?branch=dev)](https://requires.io/github/scidash/sciunit/requirements/?branch=dev) |
| [![Docker Build Status](https://img.shields.io/docker/build/scidash/sciunit.svg)](https://hub.docker.com/r/scidash/sciunit/builds/) |

<img src="https://raw.githubusercontent.com/scidash/assets/master/logos/SciUnit/sci-unit-square-small.png" alt="SciUnit Logo" width="400px">
Expand All @@ -15,7 +15,7 @@
[The conference paper](https://github.com/cyrus-/papers/raw/master/sciunit-icse14/sciunit-icse14.pdf)

## Documentation
[Chapter 1](https://github.com/scidash/sciunit/blob/master/docs/chapter1.ipynb) /
[Chapter 1](https://github.com/scidash/sciunit/blob/master/docs/chapter1.ipynb) /
[Chapter 2](https://github.com/scidash/sciunit/blob/master/docs/chapter2.ipynb) /
[Chapter 3](https://github.com/scidash/sciunit/blob/master/docs/chapter3.ipynb) /

Expand All @@ -37,7 +37,7 @@ Please join it if you are at all interested!
## Contributors
* [Rick Gerkin](http://rick.gerk.in), Arizona State University (School of Life Science)
* [Cyrus Omar](http://cs.cmu.edu/~comar), Carnegie Mellon University (Dept. of Computer Science)

## Reproducible Research ID
RRID:[SCR_014528](https://scicrunch.org/resources/Any/record/nlx_144509-1/3faed1d9-6579-5da6-b4b4-75a5077656bb/search?q=sciunit&l=sciunit)

Expand Down
2 changes: 1 addition & 1 deletion sciunit/models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ def __getattr__(self, attr):
raise AttributeError("Model %s has no attribute %s"
% (self, attr))
return result

def __str__(self):
"""Return the model name."""
return '%s' % self.name
3 changes: 2 additions & 1 deletion sciunit/suites.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ def judge(self, models,
all the way to the root of the error.
Returns:
ScoreMatrix: The resulting scores for all test/model combos."""
ScoreMatrix: The resulting scores for all test/model combos.
"""
models = self.assert_models(models)
sm = ScoreMatrix(self.tests, models, weights=self.weights)
for model in models:
Expand Down
24 changes: 20 additions & 4 deletions sciunit/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,9 @@ def __init__(self, observation, name=None, **params):

observation_schema = None
"""A schema that the observation must adhere to (validated by cerberus).
Can also be a list of schemas, one of which the observation must match."""
Can also be a list of schemas, one of which the observation must match.
If it is a list, each schema in the list can optionally be named by putting
(name, schema) tuples in that list."""

params_schema = None
"""A schema that the params must adhere to (validated by cerberus).
Expand All @@ -84,7 +86,9 @@ def validate_observation(self, observation):
raise ObservationError("Observation mean cannot be 'None'.")
if self.observation_schema:
if isinstance(self.observation_schema, list):
schema = {'oneof_schema': self.observation_schema,
schemas = [x[1] if isinstance(x, tuple) else x
for x in self.observation_schema]
schema = {'oneof_schema': schemas,
'type': 'dict'}
else:
schema = {'schema': self.observation_schema,
Expand All @@ -95,6 +99,16 @@ def validate_observation(self, observation):
raise ObservationError(v.errors)
return observation

@classmethod
def observation_schema_names(cls):
"""Return a list of names of observation schema, if they are set."""
names = []
if cls.observation_schema:
if isinstance(cls.observation_schema, list):
names = [x[0] if isinstance(x, tuple) else 'Schema %d' % (i+1)
for i, x in enumerate(cls.observation_schema)]
return names

def validate_params(self, params):
"""Validate the params provided to the constructor.
Expand Down Expand Up @@ -281,14 +295,16 @@ def judge(self, model, skip_incapable=False, stop_on_error=True,
raise score.score # An exception.
return score

def check(self, model, skip_incapable=True, stop_on_error=True):
def check(self, model, skip_incapable=True, stop_on_error=True,
require_extra=False):
"""Check to see if the test can run this model.
Like judge, but without actually running the test. Just returns a Score
indicating whether the model can take the test or not.
"""
try:
if self.check_capabilities(model, skip_incapable=skip_incapable):
if self.check_capabilities(model, skip_incapable=skip_incapable,
require_extra=require_extra):
score = TBDScore(None)
else:
score = NAScore(None)
Expand Down
36 changes: 23 additions & 13 deletions sciunit/validators.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
"""Cerberus validator classes for SciUnit."""

from cerberus import Validator, TypeDefinition
import inspect

import quantities as pq
from cerberus import TypeDefinition, Validator


def register_type(cls, name):
Expand Down Expand Up @@ -53,27 +55,35 @@ def _validate_units(self, has_units, key, value):
class ParametersValidator(Validator):
"""Cerberus validator class for observations."""

units_map = {'time': 's', 'voltage': 'V', 'current': 'A'}

def validate_quantity(self, value):
"""Validate that the value is of the `Quantity` type."""
if not isinstance(value, pq.quantity.Quantity):
self._error('%s' % value, "Must be a Python quantity.")

def _validate_type_time(self, value):
"""Validate fields requiring `units` of seconds."""
def validate_units(self, value):
"""Validate units, assuming that it was called by _validate_type_*."""
self.validate_quantity(value)
if not value.simplified.units == pq.s:
self._error('%s' % value, "Must have dimensions of time.")
self.units_type = inspect.stack()[1][3].split('_')[-1]
assert self.units_type, ("`validate_units` should not be called "
"directly. It should be called by a "
"_validate_type_* methods that sets "
"`units_type`")
units = getattr(pq, self.units_map[self.units_type])
if not value.simplified.units == units:
self._error('%s' % value,
"Must have dimensions of %s." % self.units_type)
return True

def _validate_type_time(self, value):
"""Validate fields requiring `units` of seconds."""
return self.validate_units(value)

def _validate_type_voltage(self, value):
"""Validate fields requiring `units` of volts."""
self.validate_quantity(value)
if not value.simplified.units == pq.V:
self._error('%s' % value, "Must have dimensions of voltage.")
return True
return self.validate_units(value)

def _validate_type_current(self, value):
"""Validate fields requiring `units` of amps."""
self.validate_quantity(value)
if not value.simplified.units == pq.A:
self._error('%s' % value, "Must have dimensions of current.")
return True
return self.validate_units(value)

0 comments on commit 335ae84

Please sign in to comment.