Пример #1
0
class FlowGeom(Polygon):
    """
    A `FlowGeom` is a geometric representation of a flow from
    a begin node to end node.
    """
    angular_thickness = Field(
        """
        Thickness of the flow, measured in radians
        """,
        __default_value__=0.05)
    network_geom = Field(
        """
        An object that will produce sides of the polygon to be
        drawn for this `FlowGeom`.
        """)
    begin_node_geom = Field(
        """
        The node geometry where this flow begins.
        """)
    end_node_geom = Field(
        """
        The node geometry where this flow ends.
        """)

    @lazyfield
    def sides(self):
        """
        Sides of this flow.
        """
        return self.network_geom.get_sides(self)
Пример #2
0
class NodeGeom(Polygon):
    """
    Geometry to represent nodes.
    Nodes will be placed on the circumference of a circle.
    """
    network_geom = Field(
        """
        The network geometry that controls this `NodeGeom`.
        """)
    position = Field(
        """
        Position of this node --- type should be determined by
        the network geometry object.
        """)
    thickness = Field(
        """
        Thickness of this node --- type should be the same as position.
        """)

    @lazyfield
    def sides(self):
        """
        Sides to determine where this node geometry should be placed.
        """
        return self.network_geom.get_sides(self)
Пример #3
0
class Sphere(WithFields):
    """
    Region in 3D
    """
    position_center = Field(
        """
        Three dimensional array providing position of the cube's center.
        """)
    radius = Field(
        """
        Radius of the sphere
        """)
    closed = Field(
        """
        Is the sphere closed?
        """,
        __default_value__=True)

    @property
    def volume(self):
        return (4. / 3.) * math.pi * math.pow(self.radius, 3)

    @property
    def bbox(self):
        return (self.center - self.radius, self.center + self.radius)

    def contains(self, position):
        check = np.less_equal if self.closed else np.less
        return check(
            np.linalg.norm(position - self.center, axis=0),
            self.radius)
Пример #4
0
class AnalysisSpec(WithFields):
    """
    Specify a brain-circuit analysis.
    """
    sample_size = Field("""
        Number of individual sample measurements for each set of
        parameter values.
        """,
                        __default_value__=100)
    size_roi = Field("""
        Size of ROIs that will be sampled in circuit's physical space.
        """,
                     __default_value__=50. * np.ones(3))
    path_reports = Field("""
        Location where the reports will be posted.
        """,
                         __default_value__=os.path.join(
                             os.getcwd(), "reports"))
    morphologies_interneurons = Field("""
        Interneuron morphologies that are stained by markers.
        """,
                                      __default_value__=[
                                          "BP", "BTC", "CHC", "DB", "LBC",
                                          "NBC", "MC", "SBC", "SSC"
                                      ])
    number_cortical_thickness_bins = Field("""
        Number of bins for by depth or by height analyses.
        """,
                                           __default_value__=np.int(50))
Пример #5
0
class Document(WithFields):
    """
    The root document
    """
    title = Field("""
        Title of this document element.
        """)
    author = Field("""
        Author of this document.
        """,
                   __default_value__=Author.anonymous)

    chapters = Field("""
        A chapter is any document that may have sections.
        """,
                     __default_value__=[])

    def __init__(self, title, *args, **kwargs):
        if "parent" not in kwargs:
            kwargs["parent"] = self
        for section in self.get_class_sections():
            name_section = section.__attr_name__
            if name_section in kwargs:
                try:
                    kwargs[name_section]["parent"] = self
                except TypeError:
                    pass
        super().__init__(title=title, *args, **kwargs)

        for chapter in self.chapters:
            chapter.parent = self

    @field
    def parent(self):
        """
        Parent of this document instance...
        """
        return None

    @field
    def sections(self):
        """
        An ordered sequence of elements contained in this document.
        """
        return OrderedDict()

    @classmethod
    def get_class_sections(cls):
        """
        Sections defined in this `Document class`
        Override this if the behavior changes.

        TODO: Figure out how to introspect attributes to automate...
        """
        return []
Пример #6
0
class SimpleUniformRandomConnectivity(CircuitConnectivity, WithFields):
    """
    A circuit in which a neuron has a prescribed efferent degree,
    and is assigned that many randomly chosen efferent neighbors.
    """
    mean_afferent_degree = Field("""
        A post-synaptic cell (irrespecitive of it's mtype) will be given
        a Poisson distributed number of afferent connections with the mean
        equal to this Field's value.
        """)
    mean_synapse_count = Field("""
        Mean number of synapses of a connection.
        """,
                               __default_value__=5)

    def get_afferent_degree(self, post_synaptic_cell, *args, **kwargs):
        """
        Number of out-going connections of a neuron of given 'mtype'.
        """
        return\
            np.random.poisson(self.mean_afferent_degree)

    def _synapse_count(self, *args, **kwargs):
        return 1. + np.random.poisson(self.mean_synapse_count)

    def get_synapse_counts(self, connections):
        """
        ...
        """
        return\
            1. + np.random.poisson(
                self.mean_synapse_count,
                size=connections.shape[0])

    def get_afferent_gids(self, post_synaptic_cell, cells):
        """
        GIDs of cells afferent on a post-synaptic cell.
        Arguments
        -------------
        post_gid :: GID of the post_synaptic cell.
        cells :: pandas.DataFrame containing cells in the circuit
        """
        return\
            np.sort(np.random.choice(
                cells.index.values,
                self.get_afferent_degree(post_synaptic_cell),
                replace=False))

    def get_afferent_connections(self, post_gid, post_cell, cells):
        """...
        """
        return pd.DataFrame({
            "pre_gid": self.get_afferent_gids(post_cell, cells),
            "post_gid": post_gid
        })
Пример #7
0
class Geometry(ABC, WithFields):
    """
    Base class for Geometries.
    """
    label = Field(
        """
        A label to be displayed.
        """)
    children = Field(
        """
        `Geometry`s spawned from this `Geometry`.
        """,
        __default_value__=[])
    
    @lazyfield
    def identifier(self):
        """
        Identifier can be used as a key in a mapping providing
        features for this `Geometry`.
        Override the return to specialize...
        """
        return self.label

    def spawn(self,
            type_geometry,
            *args, **kwargs):
        """
        Create a new geometry.
        """
        self.children.append(type_geometry(*args, **kwargs))
        return self.children

    @abstractmethod
    def points(self, number):
        """
        Points on this `Geometry`'s boundary.
        """
        raise NotImplementedError

    @abstractmethod
    def _draw_this(self,
            *args, **kwargs):
        """
        Draw only this geometry.
        """
        raise NotImplementedError
        
    def draw(self,
            *args, **kwargs):
        """
        Draw this geometry, and all the geometries it has spawned.
        """
        for child in self.children:
            child.draw(*args, **kwargs)
        return self._draw_this(*args, **kwargs)
Пример #8
0
class CircuitAnalysisReport(Report):
    """
    Add some circuit analysis specific attributes to `Report`
    """
    provenance_model = Field("""
        Either a `class CircuitProvenance` instance or a dict providing values
        for the fields of `class CircuitProvenance`.
        """,
                             __as__=CircuitProvenance)
    figures = Field("""
        A dict mapping label to an object with a `.graphic` and `.caption`
        attributes.
        """,
                    __default_value__={})
    references = Field("""
        References of literature cited in this report.
        """,
                       __type__=Mapping,
                       __default_value__={})
    content = LambdaField(
        """
        All text as a single string.
        """, lambda self: (self.abstract + self.introduction + self.methods +
                           self.results + self.discussion))

    @lazyfield
    def field_values(self):
        """..."""
        try:
            name_phenomenon = self.phenomenon.name
        except AttributeError:
            name_phenomenon = make_name(self.phenomenon, separator="-")
        return\
            dict(
                circuit=OrderedDict((
                    ("animal", self.provenance_model.animal),
                    ("age", self.provenance_model.age),
                    ("brain_region", self.provenance_model.brain_region),
                    ("uri", self.provenance_model.uri),
                    ("references", self.references),
                    ("date_release", self.provenance_model.date_release),
                    ("authors", '; '.join(
                        "{}. {}".format(i+1, a)
                        for i, a in enumerate(self.provenance_model.authors))))),
                author=self.author,
                phenomenon=name_phenomenon,
                label=make_label(self.label, separator='-'),
                title=make_name(self.label, separator='-'),
                abstract=self.abstract,
                introduction=self.introduction,
                methods=self.methods,
                results=self.results,
                content=self.content,
                discussion=self.discussion)
Пример #9
0
class Cuboid(WithFields):
    """
    A region.
    """
    position_corner_0 = Field(
        """
        A corner of this cuboid.
        """)
    position_corner_1 = Field(
        """
        Another corner of this cuboid, diagonally opposite to the other.
        """)
    closed = Field(
        """
        Is the geometry closed?
        """,
        __default_value__=True)

    def __init__(self,
            positions_corner_0,
            positions_corner_1,
            closed=False,
            *args, **kwargs):
        """..."""
        super().__init__(
            *args,
            position_corner_0=positions_corner_0,
            position_corner_1=positions_corner_1,
            closed=closed,
            **kwargs)


    @property
    def volume(self):
        """
        Volume of this cuboid.
        """
        return np.abs(np.prod(self.position_corner_0, self.position_corner_1))

    @property
    def bbox(self):
        """
        A box that bounds this cuboid.
        """
        return (self.position_corner_0, self.position_corner_1)

    def contains(self, position):
        """???"""
        check = np.less_equal if self.closed else np.less
        return np.all(
            np.logical_and(
                check(self.position_corner_0, position),
                check(self.position_corner_1, position)),
        axis=1)
Пример #10
0
    class Collector(WithFields):
        """
        Collect a measurement...
        """
        label = Field("""
            Single word string to name the measurement column.
            """,
                      __default_value__="value")
        sample_size = Field("""
            Number of repetitions for each set of parameter values.
            """,
                            __default_value__=1)

        @field.cast(Parameters)
        def parameters(self):
            """
            Parameter sets to measure with.
            Or a callable that produces such parameters...
            """
            raise FieldIsRequired

        @field
        def method(self, *args, **kwargs):
            """
            That makes a measurement.
            """
            raise FieldIsRequired

        @field
        def collection(self):
            """
            A policy to collect the measurements over all parameter sets
            """
            return measurement_collection.primitive_type

        def __call__(self, adapter, model, *args, **kwargs):
            """
            Collect a measurement
            """
            return\
                self.collection(
                    (p, self.method(adapter, model, **p, **kwargs))
                    for p in self.parameters(
                            adapter, model,
                            sample_size=self.sample_size,
                            **kwargs)
                ).rename(
                    columns={"value": self.label}
                )
Пример #11
0
class SynapseCollection(WithFields):
    """
    A collection of synapses that stores synapses.
    SynapseCollection builds on pandas DataFrame to store data
    in memory, and provides an efficient secondary index on the stored data.
    If there are two many synapses to store in memory, SynapseCollection will
    respond to queries by loading the data from disk.

    """
    adjacency = Field("""
        List of 2-tuples holding connected cell gid and synapse count.
        """)
    direction = Field("""
        Direction of the connections in 'adjacency' data.
        """)
Пример #12
0
class Figure(WithFields):
    """
    A `Figure` is a graphic with a caption.
    """
    graphic = Field("""
        A matplotlib figure, or PDF, PNG...
        """)
    caption = Field("""
        A text to go with the graphic.
        """,
                    __as__=paragraphs)

    def __init__(self, figure, caption="No caption provided", *args, **kwargs):
        """
        Initialize with graphic as an argument.
        `WithField` provides an `__init__` method that accepts initializer
        arguments as keyword arguments.
        However, with this `__init__` method we cannot pass the graphic as a
        keyword argument.

        We still allow `*args, **kwargs` that will allow `class Figure` to be
        mixed in some other class.
        """
        try:
            graphic = figure.graphic
        except AttributeError:
            graphic = figure
        super().__init__(graphic=graphic, caption=caption, *args, **kwargs)

    def save(self, path, dpi=100):
        """
        Save the figure.
        """
        if isinstance(self.graphic, (str, Path)):
            shutil.copy(self.graphic, path)
            return path
        try:
            result = self.graphic.savefig(path, dpi=dpi)
        except AttributeError:
            try:
                result = self.graphic.figure.savefig(path, dpi=dpi)
            except AttributeError:
                raise TypeError("Figure type {} not supported".format(
                    self.graphic.__class__))
            result = None
        return result
Пример #13
0
class CircuitProvenance(WithFields):
    """
    Provenance of a circuit.
    """
    label = Field("""
        A label that names the circuit model.
        """,
                  __default_value__="")
    authors = Field("""
        A list of authors who built the circuit model.
        """,
                    __default_value__=["Not Available"])
    date_release = Field("""
        When the circuit model was released in its final form.
        """,
                         __default_value__="YYYYMMDD")
    uri = Field("""
        URI from where the circuit model can be loaded.
        """,
                __default_value__="https://www.example.com")
    animal = Field("""
        The animal whose brain was modeled.
        """,
                   __default_value__="Not Available")
    age = Field("""
        Age of the animal at which its brain was modeled.
        """,
                __default_value__="XYZ Weeks")
    brain_region = Field("""
        Brain region that was modeled.
        """,
                         __default_value__="Somatosensory Cortex (SSCx)")
Пример #14
0
class Arc(Circle):
    """
    Part of a circle.
    """
    angle_begin = Field(
        """
        Angle at which the arc starts.
        """)
    angle_end = Field(
        """
        Angle at which the arc stops.
        """)
    def points(self, number=100):
        """..."""
        return self.segment_points(
            angle_begin=self.angle_begin,
            angle_end=self.angle_end,
            number=number)
Пример #15
0
class Polygon(Geometry):
    """
    Polygon is a sequences of vertices.
    """
    sides = Field(
        """
        Sequence of `Paths`
        """)
    facecolor = Field(
        """
        Colors to use for this `Polygon`.
        """,
        __default_value__="red")

    def points(self, number=None):
        """
        Points of a given number does not make sense.
        """
        return [
            point for side in self.sides
            for point in side.vertices]

    def _draw_this(self,
            axes=None,
            *args, **kwargs):
        """
        Draw this polygon.
        """
        if axes is None:
            axes = plt.gca()

        patch_polygon =\
            PatchPolygon(
                np.vstack([
                    side.vertices
                    for side in self.sides]))
        axes.add_collection(
            PatchCollection(
                [patch_polygon],
                facecolors=(self.facecolor,),
                edgecolors=("grey",),
                linewidths=(1,),))
                
        return axes
Пример #16
0
class Interval(WithFields):
    """
    An `Interval` is two floats.
    """
    bottom = Field(
        """
        The bottom of the interval.
        """)
    top = Field(
        """
        The top of the interval,.
        """)

    @lazyfield
    def thickness(self):
        """
        Thickness is the length of the this `Interval`.
        """
        return self.top - self.bottom
Пример #17
0
class QueryDB(WithFields):
    """
    Cache of data associated with a circuit query, that the adapter will use.
    """
    method_to_memoize = Field("""
        A callable to get values to cache.
        """)

    def __init__(self, method_to_memoize):
        """..."""
        super().__init__(method_to_memoize=method_to_memoize)

    @lazyfield
    def store(self):
        return {}

    @staticmethod
    def _hashable(query_dict):
        """..."""
        return tuple(
            sorted([(key, make_hashable(value))
                    for key, value in query_dict.items() if value is not None],
                   key=lambda key_value: key_value[0]))

    @staticmethod
    def _hashed(query_dict):
        """..."""
        return\
            hash(QueryDB._hashable(query_dict))

    def __call__(self, circuit_model, query_dict):
        """
        Call Me.
        """
        if circuit_model not in self.store:
            self.store[circuit_model] = {}

        cache_circuit_model = self.store[circuit_model]
        hash_query = self._hashable(query_dict)
        if hash_query not in cache_circuit_model:
            cache_circuit_model[hash_query] =\
                self.method_to_memoize(circuit_model, query_dict)

        return cache_circuit_model[hash_query]
Пример #18
0
class Path(Curve):
    """
    A curve with points on the curve provided explicitly.
    """,
    vertices = Field(
        """
        A sequence of 2D vertices that define this `Path`.
        """)

    def points(self, number=100):
        """
        Convert vertices to the number of points demanded.
        """
        if number >= len(self.vertices):
            return self.vertices
        return self.vertices[
            np.random.choice(
                range(len(self.vertices)), number, replace=False)
        ]
Пример #19
0
class DocElem(WithFields, AIBase):
    """..."""
    title = Field("""
        Title of this document element.
        """)
    label = LambdaField(
        """
        A single word tag for this document element.
        """, lambda self: make_label(self.title))

    @field
    def parent(self):
        """
        Parent `DocElem` that contains this one.
        """
        raise FieldIsRequired

    @field
    def children(self):
        """
        A sequence of `DocElem`s that are contained in this one.
        """
        return tuple()

    def save(self, record, path):
        """Save this `DocElem`"""
        try:
            save_super = super().save
        except AttributeError:
            return path
        return save_super(record, Path(path).joinpath(self.label))

    def __call__(self, adapter, model, *args, **kwargs):
        """..."""
        try:
            get_record = super().__call__
        except AttributeError:
            return Record(title=self.title, label=self.label)
        return get_record(adapter, model, *args,
                          **kwargs).assign(title=self.title, label=self.label)