Search in sources :

Example 26 with MNode

use of gov.sandia.n2a.db.MNode in project n2a by frothga.

the class ImportJob method spikingSynapse.

/**
 *        Create a spike generator, which may be associated with its intended synapse.
 */
public void spikingSynapse(Node node) {
    String id = getAttribute(node, "id");
    String synapse = getAttribute(node, "synapse");
    // "spikeTarget" appears to be redundant with "synapse". Probably exists due to some oddity in LEMS.
    MNode part = models.childOrCreate(modelName, id);
    String inherit = node.getNodeName();
    NameMap nameMap = partMap.importMap(inherit);
    inherit = nameMap.internal;
    if (!inherit.isEmpty()) {
        part.set("$inherit", inherit);
        addDependency(part, inherit);
    }
    // "spikeArray" does not have an associated synapse.
    if (!synapse.isEmpty())
        part.set("$metadata", "backend.lems.synapse", synapse);
    addAttributes(node, part, nameMap, "id", "synapse", "spikeTarget");
    Map<Double, String> sorted = new TreeMap<Double, String>();
    for (Node child = node.getFirstChild(); child != null; child = child.getNextSibling()) {
        if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("spike")) {
            String time = biophysicalUnits(getAttribute(child, "time"));
            sorted.put(Scalar.convert(time), time);
        }
    }
    if (// generate spikeArray-like code
    sorted.size() > 0) {
        String times = "";
        for (String s : sorted.values()) times += ";" + s;
        // This shuts down spiking after last specified time.
        times += ";∞";
        times = "[" + times.substring(1) + "]";
        part.set("times", times);
    }
}
Also used : Node(org.w3c.dom.Node) MNode(gov.sandia.n2a.db.MNode) NameMap(gov.sandia.n2a.backend.neuroml.PartMap.NameMap) TreeMap(java.util.TreeMap) MNode(gov.sandia.n2a.db.MNode)

Example 27 with MNode

use of gov.sandia.n2a.db.MNode in project n2a by frothga.

the class ImportJob method typeFor.

/**
 *        Converts an element name to an internal part name, if one is available.
 */
public String typeFor(String nodeName, List<MNode> parents) {
    String query = "backend.lems.children." + nodeName;
    for (MNode parent : parents) {
        // TODO: for lookup of direct child, may need to map node name in context of parent.
        // This is only necessary if the subpart has a different internal name.
        // Assumes single inheritance
        String type = parent.get(nodeName, "$inherit").replace("\"", "");
        if (!type.isEmpty())
            return type;
        MNode c = parent.child("$metadata", query);
        if (c != null)
            return c.getOrDefault(nodeName);
    }
    return "";
}
Also used : MNode(gov.sandia.n2a.db.MNode)

Example 28 with MNode

use of gov.sandia.n2a.db.MNode in project n2a by frothga.

the class ImportJob method resolve.

public void resolve(MNode dependent) {
    dependents.remove(dependent);
    boolean isChildrenType = dependent.key().startsWith("backend.lems.children");
    boolean isConnect = dependent.get().contains("$connect");
    String dependentInherit = dependent.get("$inherit");
    // For connections, the part name might be a direct value.
    if (dependentInherit.isEmpty())
        dependentInherit = dependent.get();
    if (dependentInherit.startsWith("$connect")) {
        dependentInherit = dependentInherit.replace("$connect(", "");
        dependentInherit = dependentInherit.replace(")", "");
    }
    String[] sourceNames = dependentInherit.split(",");
    for (int sourceIndex = 0; sourceIndex < sourceNames.length; sourceIndex++) {
        String sourceName = sourceNames[sourceIndex].replace("\"", "");
        MNode source = models.child(modelName, sourceName);
        if (source == null)
            continue;
        // Ensure that the source part has no unresolved dependencies of its own before using it.
        resolveChildren(source);
        boolean proxy;
        if (source.child("$proxy") == null) {
            proxy = true;
            String inherit = source.key();
            for (MNode c : source) {
                String key = c.key();
                if (key.equals("$count"))
                    continue;
                if (key.equals("$connected"))
                    continue;
                if (key.equals("$lems"))
                    continue;
                if (key.equals("$lemsUses"))
                    continue;
                // Inheriting our own name is characteristic of being a proxy.
                if (key.equals("$inherit") && c.get().replace("\"", "").equals(inherit))
                    continue;
                // key is something other than our temporary special keys, so not shallow
                proxy = false;
                break;
            }
            if (proxy) {
                // proxies only have single inheritance
                source.set("$inherit", "\"" + inherit + "\"");
                MNode parent = AppData.models.child(inherit);
                if (parent == null) {
                    source.set("$proxy", "1");
                } else {
                    source.set("$proxy", "found");
                    String id = parent.get("$metadata", "id");
                    if (!id.isEmpty())
                        source.set("$inherit", "0", id);
                }
            } else {
                source.set("$proxy", "0");
            }
        } else {
            proxy = !source.get("$proxy").equals("0");
        }
        // Triage
        // -1 == source has exactly one user. Merge and delete immediately.
        // -2 == source is lightweight, but has multiple users. Merge and wait to delete.
        // -3 == source is heavyweight. Keep reference and move out to independent model.
        // -4 == source is the endpoint of a connection. Leave in place.
        // Note that a "lightweight" part could also be a proxy, in which case it is an external reference.
        // A proxy is configured (above) to inherit the external model, so when the part is merged,
        // the dependent will end up referring directly to the external model.
        int count = source.getInt("$count");
        boolean connected = source.child("$connected") != null;
        boolean lemsUses = source.child("$lemsUses") != null;
        if (// triage is necessary
        count > 0) {
            if (lemsUses && !proxy) {
                // Anything a LEMS component depends on must be even more abstract, and thus should be an independent model.
                count = -3;
            } else if (connected) {
                if (// One dependent, with only one connection target, so OK to embed.
                dependent.getOrDefaultInt("$n", "1") == 1 && count == 1)
                    // One dependent, with only one connection target, so OK to embed.
                    count = -1;
                else
                    // Otherwise, the source should be separate from the connection part.
                    count = -4;
            } else if (count == 1) {
                count = -1;
            } else // count > 1 and not connected, so could be moved out to independent model
            {
                // Criterion: If a part has subparts, then it is heavy-weight and should be moved out.
                // A part that merely sets some parameters on an inherited model is lightweight, and should simply be merged everywhere it is used.
                boolean heavy = false;
                for (MNode s : source) {
                    if (MPart.isPart(s)) {
                        heavy = true;
                        break;
                    }
                }
                if (heavy)
                    count = -3;
                else
                    count = -2;
            }
            source.set("$count", count);
            if (count == -3) {
                MNode id = source.childOrCreate("$metadata", "id");
                if (id.get().isEmpty())
                    id.set(AddDoc.generateID());
            }
        }
        if (count == -1 || count == -2) {
            if (// Those two node types don't receive part injection, and don't change the name they use to reference the part.
            !isChildrenType && !isConnect) {
                dependent.set("");
                sourceNames[sourceIndex] = source.get("$inherit");
                String inherit = "";
                for (int i = 0; i < sourceNames.length; i++) inherit += "," + sourceNames[i];
                inherit = inherit.substring(1);
                if (// This can happen if source is a Cell, which currently lacks a base class since it is merely a container for segments.
                inherit.isEmpty()) {
                    dependent.clear("$inherit");
                } else {
                    dependent.set("$inherit", inherit);
                    // Assume single-inheritance in sources
                    dependent.set("$inherit", sourceIndex, source.get("$inherit", "0"));
                }
                for (MNode n : source) {
                    String key = n.key();
                    if (key.equals("$count"))
                        continue;
                    if (key.equals("$connected"))
                        continue;
                    if (key.equals("$lems"))
                        continue;
                    if (key.equals("$lemsUses"))
                        continue;
                    if (key.equals("$proxy"))
                        continue;
                    // already handled above
                    if (key.equals("$inherit"))
                        continue;
                    MNode c = dependent.child(key);
                    if (c == null)
                        dependent.set(key, n);
                    else
                        c.mergeUnder(n);
                }
                if (!proxy)
                    dependent.set("$metadata", "backend.lems.id", sourceName);
            }
            if (count == -1)
                models.clear(modelName, sourceName);
        } else if (count == -3) {
            String inherit = modelName + " " + sourceName;
            String id = source.get("$metadata", "id");
            if (isChildrenType) {
                // TODO: Can't store ID under metadata node, but could tack it on the end as a comma-separated value.
                dependent.set(inherit);
            } else if (isConnect) {
                dependent.set("$connect(\"" + inherit + "\")");
            // dependent.set ("0", id);  // TODO: Store ID with $connect() ?
            } else {
                sourceNames[sourceIndex] = "\"" + inherit + "\"";
                inherit = "";
                for (int i = 0; i < sourceNames.length; i++) inherit += "," + sourceNames[i];
                dependent.set("$inherit", inherit.substring(1));
                dependent.set("$inherit", sourceIndex, id);
            }
        }
    }
}
Also used : MNode(gov.sandia.n2a.db.MNode)

Example 29 with MNode

use of gov.sandia.n2a.db.MNode in project n2a by frothga.

the class ImportJob method simulation.

public void simulation(Node node) {
    String id = getAttribute(node, "id");
    String length = getAttribute(node, "length");
    String step = getAttribute(node, "step");
    String target = getAttribute(node, "target");
    // redirect, since "Simulation" itself is not a proper object.
    if (primaryModel.equals(id))
        primaryModel = target;
    MNode part = models.childOrCreate(modelName, target);
    part.set("$t'", step);
    part.set("$p", "$t<" + length);
    for (Node child = node.getFirstChild(); child != null; child = child.getNextSibling()) {
        if (child.getNodeType() == Node.ELEMENT_NODE)
            output(child, part);
    }
}
Also used : Node(org.w3c.dom.Node) MNode(gov.sandia.n2a.db.MNode) MNode(gov.sandia.n2a.db.MNode)

Example 30 with MNode

use of gov.sandia.n2a.db.MNode in project n2a by frothga.

the class ImportJob method collectParents.

/**
 *        Locates all the accessible parents of the given node and lists them in ascending
 *        order by distance from child. That is, most direct ancestor comes first in the list.
 *        In addition to terminating at the root parent, also terminates when a parent can't
 *        be found, so the list may be incomplete.
 */
public List<MNode> collectParents(MNode child) {
    List<MNode> result = new ArrayList<MNode>();
    String childInherit = child.get("$inherit");
    String[] inherits = childInherit.split(",");
    for (String inherit : inherits) {
        inherit = inherit.replace("\"", "");
        if (inherit.isEmpty())
            continue;
        MNode parent = models.child(modelName, inherit);
        // Prevent infinite loop on proxies.
        if (parent == child)
            parent = null;
        if (parent == null)
            parent = AppData.models.child(inherit);
        if (parent == null)
            continue;
        result.add(parent);
        result.addAll(collectParents(parent));
    }
    return result;
}
Also used : ArrayList(java.util.ArrayList) MNode(gov.sandia.n2a.db.MNode)

Aggregations

MNode (gov.sandia.n2a.db.MNode)63 Node (org.w3c.dom.Node)11 NameMap (gov.sandia.n2a.backend.neuroml.PartMap.NameMap)9 MVolatile (gov.sandia.n2a.db.MVolatile)5 MPart (gov.sandia.n2a.eqset.MPart)5 ArrayList (java.util.ArrayList)5 PanelModel (gov.sandia.n2a.ui.eq.PanelModel)4 MPersistent (gov.sandia.n2a.db.MPersistent)3 EquationSet (gov.sandia.n2a.eqset.EquationSet)3 Variable (gov.sandia.n2a.eqset.Variable)3 AccessVariable (gov.sandia.n2a.language.AccessVariable)3 PanelReference (gov.sandia.n2a.ui.ref.PanelReference)3 Element (org.w3c.dom.Element)3 NamedNodeMap (org.w3c.dom.NamedNodeMap)3 MDoc (gov.sandia.n2a.db.MDoc)2 ParseException (gov.sandia.n2a.language.ParseException)2 AddDoc (gov.sandia.n2a.ui.eq.undo.AddDoc)2 IOException (java.io.IOException)2 TreeMap (java.util.TreeMap)2 IncommensurableException (javax.measure.IncommensurableException)2