Ejemplo n.º 1
0
def make_big_system(cortical_areas=None):
    # complications:
    # - AIP connections studied by Borra but not in CoCoMac
    # - CIP should maybe be split from LIP (or related to PIP?)
    # - pulvinar connectivity
    # - how to normalize FLNe
    # V6, V6A: should really use Shipp et al. 2001 rather than CoCoMac, but map to PO for now

    system = System()
    w_rf_0 = 0.2
    system.add_input(750000, w_rf_0)

    # Estimates of LGN cell numbers (one side) from:
    # Weber, Arthur J., et al. (2000) Experimental glaucoma and cell size, density, and number in the primate lateral
    # geniculate nucleus. Investigative ophthalmology & visual science 41.6: 1370 - 1379.
    n_LGN = 1270000
    n_magno_LGN = 0.103 * n_LGN
    n_parvo_LGN = 0.897 * n_LGN

    # Weber et al. say, "For normal animals, the total number of neurons in the LGN was estimated to be
    # approximately 1.27 million, with 10.3% located in the M-layers and 89.7% in the P-layers." Koniocellular
    # neurons are between these layers, and similar in number to M cells, so we'll add another 10.3%
    n_konio_LGN = 0.103 * n_LGN

    # Guessing convergence from RGC to LGN based on comments page 54 of:
    # Lee, B.B., Virsu, V., & Creutzfeldt, O.D.(1983).Linear signal transmission from prepotentials to cells in the
    # macaqie lateral geniculate nucleus. Experimental Brain Research, 52(1), 50 - 56.
    convergence_LGN = 5

    # See also re. parallel projections from retina to LGN:
    # Leventhal, A.G., Rodieck, R.W., & Dreher, B.(1981).Retinal ganglion cell classes in the Old World
    # monkey: morphology and central projections. Science, 213(4512), 1139 - 1142.

    # Magno cells have slightly larger RFs than parvo:
    # Derrington, A.M., & Lennie, P.(1984).Spatial and temporal contrast sensitivities of neurones in lateral
    # geniculate nucleus of macaque.The Journal of Physiology, 357(1), 219 - 240.

    # Pixels correspond roughly to retinal ganglion cells
    # Setting LGN RF sizes similar to input (one-pixel kernels)
    system.add("parvo_LGN", n_parvo_LGN, 5, 1.041 * w_rf_0)
    system.add("magno_LGN", n_magno_LGN, 5, 1.155 *
               w_rf_0)  # TODO reconsider; see Livingston & Hubel (1988)
    system.add(
        "konio_LGN", n_konio_LGN, 5, 1.155 * w_rf_0
    )  # RF sizes highly scattered but comparable to Magno (Xu et al., 2004, J Physiol)
    system.connect_areas(system.input_name, "parvo_LGN", 1.0)
    system.connect_areas(system.input_name, "magno_LGN", 1.0)
    system.connect_areas(system.input_name, "konio_LGN", 1.0)

    # L4A is omitted in classical models, so we leave it out, but see (Sincich et al. 2010)
    for layer in [
            "4Calpha", "4Cbeta", "4B", "2/3blob", "2/3interblob", "5", "6"
    ]:
        if "2/3" in layer:
            n = _get_num_ff_neurons("V1", "2/3")
            if "blob" in layer:
                n = n / 3  # Sincich et al. (2010, J Neurosci)
            elif "interblob" in layer:
                n = 2 * n / 3
        else:
            n = _get_num_ff_neurons("V1", layer)

        e = data.get_extrinsic_inputs("V1",
                                      "4") if layer.startswith("4C") else None

        # Livingston & Hubel (1988) cite Livingston & Hubel (1984) re larger RF sizes in blobs
        # than interblobs, but I can't find anything about this in the 1984 paper (or elsewhere).
        if "4C" in layer:
            w = data.get_receptive_field_size("V1")
        else:
            w = None
        system.add("V1_{}".format(layer), n, e, w)

    system.connect_areas("parvo_LGN", "V1_4Cbeta", 1.0)
    system.connect_areas("magno_LGN", "V1_4Calpha", 1.0)
    system.connect_areas("konio_LGN", "V1_2/3blob", 1.0)
    system.connect_areas("konio_LGN", "V1_2/3interblob", 1.0)
    system.connect_layers("V1_4Calpha", "V1_4B",
                          data.get_inputs_per_neuron("V1", "4", "2/3"))
    system.connect_layers("V1_4Cbeta", "V1_2/3blob",
                          0.5 * data.get_inputs_per_neuron("V1", "4", "2/3"))
    system.connect_layers("V1_4Cbeta", "V1_2/3interblob",
                          data.get_inputs_per_neuron("V1", "4", "2/3"))

    # feedforward magno input to ventral areas (see Merigan & Maunsell, 1983, pg 386)
    system.connect_layers("V1_4Calpha", "V1_2/3blob",
                          0.5 * data.get_inputs_per_neuron("V1", "4", "2/3"))

    # Tootell et al. (1988) (IV)
    system.connect_layers("V1_2/3blob", "V1_5",
                          0.5 * data.get_inputs_per_neuron("V1", "2/3", "5"))
    system.connect_layers("V1_2/3interblob", "V1_5",
                          0.5 * data.get_inputs_per_neuron("V1", "2/3", "5"))
    system.connect_layers("V1_4Cbeta", "V1_5",
                          data.get_inputs_per_neuron("V1", "4", "5"))

    system.connect_layers("V1_2/3blob", "V1_6",
                          data.get_inputs_per_neuron("V1", "2/3", "6"))
    system.connect_layers("V1_4Calpha", "V1_6",
                          data.get_inputs_per_neuron("V1", "4", "6"))
    system.connect_layers("V1_5", "V1_6",
                          data.get_inputs_per_neuron("V1", "5", "6"))

    for area in ["V2thick", "V2thin", "V2pale"]:
        for layer in ["2/3", "4", "5", "6"]:
            name = _pop_name(area, layer)

            n = _get_num_ff_neurons("V2", layer)
            n = n / 5 if "thin" in area else 2 * n / 5

            e = data.get_extrinsic_inputs("V2", "4") if layer == "4" else None
            w = data.get_receptive_field_size("V2") if layer == "4" else None

            system.add(name, n, e, w)

        system.connect_layers(_pop_name(area, "4"), _pop_name(area, "2/3"),
                              data.get_inputs_per_neuron("V2", "4", "2/3"))
        system.connect_layers(_pop_name(area, "2/3"), _pop_name(area, "5"),
                              data.get_inputs_per_neuron("V2", "2/3", "5"))
        system.connect_layers(_pop_name(area, "4"), _pop_name(area, "5"),
                              data.get_inputs_per_neuron("V2", "4", "5"))
        system.connect_layers(_pop_name(area, "5"), _pop_name(area, "6"),
                              data.get_inputs_per_neuron("V2", "5", "6"))
        system.connect_layers(_pop_name(area, "2/3"), _pop_name(area, "6"),
                              data.get_inputs_per_neuron("V2", "2/3", "6"))

    # There is substantial forward projection from V1_5 to V2 and V3, also from V2_5 to V3. We assume V1_5 is
    # parvo, and V2_5 is separated into stripes. Will omit parvo, V1_5, and V2thin_5 projections to dorsal areas,
    # consistent with MT supression following magno inactivation, reported in:
    # Maunsell, J. H., Nealey, T. A., & DePriest, D. D. (1990). Magnocellular and parvocellular contributions to
    # responses in the middle temporal visual area (MT) of the macaque monkey. Journal of Neuroscience, 10(10), 3323-3334.
    FLNe = data.get_FLNe("V1", "V2")
    SLN = data.get_SLN("V1", "V2")
    system.connect_areas("V1_2/3blob", "V2thin_4", FLNe * SLN / 100)
    system.connect_areas("V1_2/3interblob", "V2pale_4", FLNe * SLN / 100)
    system.connect_areas("V1_5", "V2thin_4", FLNe * (1 - SLN / 100))
    system.connect_areas("V1_4B", "V2thick_4", FLNe * SLN / 100)

    if system.find_population_index("MT_4"):
        FLNe = data.get_FLNe("V1", "MT")
        SLN = data.get_SLN("V1", "MT")
        system.connect_areas("V1_6", "MT_4", FLNe * (1 - SLN / 100))

    # Dorsal areas get connections from V1_4B and V2thick; ventral from V1_2/3, V1_5, and V2_thin
    # References on segregation in V2:
    # Shipp, S., & Zeki, S. (1985). Segregation of pathways leading from area V2 to areas V4 and V5 of
    # macaque monkey visual cortex. Nature, 315(6017), 322.
    # DeYoe, E. A., & Van Essen, D. C. (1985). Segregation of efferent connections and receptive field
    # properties in visual area V2 of the macaque. Nature, 317(6032), 58.
    # Sincich, L. C., & Horton, J. C. (2002). Divided by cytochrome oxidase: a map of the projections
    # from V1 to V2 in macaques. Science, 295(5560), 1734-1737.
    # DeYoe, E. A., & Van Essen, D. C. (1988). Concurrent processing streams in monkey visual cortex.
    # Trends in neurosciences, 11(5), 219-226.

    if cortical_areas is None:
        cortical_areas = data.get_areas()[:]
        cortical_areas.remove("MDP")  # MDP has no inputs in CoCoMac

    add_areas(system, [a for a in cortical_areas if a not in ("V1", "V2")])
    connect_areas_in_streams(system, cortical_areas)

    # It's correct to have this after making connections, as it operates
    # on actual connections between populations rather than raw FLNe data.
    system.normalize_FLNe()

    system.check_connected()

    return system