org.geppetto.model.neuroml.services.NeuroMLModelInterpreterService.java Source code

Java tutorial

Introduction

Here is the source code for org.geppetto.model.neuroml.services.NeuroMLModelInterpreterService.java

Source

/*******************************************************************************
. * The MIT License (MIT)
 *
 * Copyright (c) 2011, 2013 OpenWorm.
 * http://openworm.org
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the MIT License
 * which accompanies this distribution, and is available at
 * http://opensource.org/licenses/MIT
 *
 * Contributors:
 *        OpenWorm - http://openworm.org/people.html
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 * USE OR OTHER DEALINGS IN THE SOFTWARE.
 *******************************************************************************/

package org.geppetto.model.neuroml.services;

import java.io.IOException;
import java.math.BigInteger;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.UUID;

import javax.xml.bind.JAXBException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.geppetto.core.beans.ModelInterpreterConfig;
import org.geppetto.core.model.IModel;
import org.geppetto.core.model.IModelInterpreter;
import org.geppetto.core.model.ModelInterpreterException;
import org.geppetto.core.model.ModelWrapper;
import org.geppetto.core.model.runtime.ANode;
import org.geppetto.core.model.runtime.AspectNode;
import org.geppetto.core.model.runtime.AspectSubTreeNode;
import org.geppetto.core.model.runtime.AspectSubTreeNode.AspectTreeType;
import org.geppetto.core.model.runtime.EntityNode;
import org.geppetto.core.utilities.URLReader;
import org.geppetto.core.utilities.VariablePathSerializer;
import org.geppetto.core.visualisation.model.Point;
import org.geppetto.model.neuroml.utils.LEMSAccessUtility;
import org.geppetto.model.neuroml.utils.NeuroMLAccessUtility;
import org.geppetto.model.neuroml.utils.OptimizedLEMSReader;
import org.geppetto.model.neuroml.utils.PopulateModelTree;
import org.geppetto.model.neuroml.utils.Resources;
import org.lemsml.jlems.core.api.LEMSDocumentReader;
import org.lemsml.jlems.core.api.interfaces.ILEMSDocument;
import org.lemsml.jlems.core.api.interfaces.ILEMSDocumentReader;
import org.lemsml.jlems.core.sim.ContentError;
import org.lemsml.jlems.core.type.Component;
import org.lemsml.jlems.core.type.Lems;
import org.neuroml.model.Base;
import org.neuroml.model.BaseCell;
import org.neuroml.model.Instance;
import org.neuroml.model.Location;
import org.neuroml.model.Network;
import org.neuroml.model.NeuroMLDocument;
import org.neuroml.model.Population;
import org.neuroml.model.PopulationTypes;
import org.neuroml.model.util.NeuroMLConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author matteocantarelli
 * 
 */
@Service
public class NeuroMLModelInterpreterService implements IModelInterpreter {
    private NeuroMLAccessUtility neuroMLAccessUtility = new NeuroMLAccessUtility();

    private static Log _logger = LogFactory.getLog(NeuroMLModelInterpreterService.class);

    // helper class to populate model tree
    private PopulateModelTree populateModelTree = new PopulateModelTree();

    @Autowired
    private ModelInterpreterConfig neuroMLModelInterpreterConfig;

    /*
     * (non-Javadoc)
     * 
     * @see org.openworm.simulationengine.core.model.IModelProvider#readModel(java .lang.String)
     */
    public IModel readModel(URL url, List<URL> recordings, String instancePath) throws ModelInterpreterException {
        ModelWrapper model = new ModelWrapper(instancePath);
        try {
            Scanner scanner = new Scanner(url.openStream(), "UTF-8");
            String neuroMLString = scanner.useDelimiter("\\A").next();
            scanner.close();
            String lemsString = NeuroMLConverter.convertNeuroML2ToLems(neuroMLString);

            ILEMSDocumentReader lemsReader = new LEMSDocumentReader();
            //ILEMSDocument document = lemsReader.readModel(lemsString);

            int index = url.toString().lastIndexOf('/');
            String urlBase = url.toString().substring(0, index + 1);

            OptimizedLEMSReader reader = new OptimizedLEMSReader(urlBase);
            String lemsStringOptimized = reader.processLEMSInclusions(lemsString);
            lemsStringOptimized = reader.processLEMSInclusions(lemsStringOptimized, false);
            ILEMSDocument document = lemsReader.readModel(lemsStringOptimized);

            //         NeuroMLConverter neuromlConverter = new NeuroMLConverter();
            //         NeuroMLDocument neuroml = neuromlConverter.urlToNeuroML(url);

            NeuroMLConverter neuromlConverter = new NeuroMLConverter();
            String neuromlString = URLReader.readStringFromURL(url);
            NeuroMLDocument neuroml = neuromlConverter.loadNeuroML(neuromlString);

            String neuromlStringOptimized = reader.processLEMSInclusions(neuromlString, false);
            neuromlStringOptimized = reader.processLEMSInclusions(neuromlStringOptimized);
            NeuroMLDocument neuroml_inclusions = neuromlConverter.loadNeuroML(neuromlStringOptimized);

            model = new ModelWrapper(UUID.randomUUID().toString());
            model.setInstancePath(instancePath);
            // two different interpretations of the same file, one used to simulate the other used to visualize
            model.wrapModel(NeuroMLAccessUtility.LEMS_ID, document);
            //model.wrapModel(NeuroMLAccessUtility.LEMS_ID_INCLUSIONS, document_inclusions);
            model.wrapModel(NeuroMLAccessUtility.NEUROML_ID, neuroml);
            model.wrapModel(NeuroMLAccessUtility.NEUROML_ID_INCLUSIONS, neuroml_inclusions);
            model.wrapModel(NeuroMLAccessUtility.URL_ID, url);
            model.wrapModel(NeuroMLAccessUtility.SUBENTITIES_MAPPING_ID, new HashMap<String, EntityNode>());
            model.wrapModel(NeuroMLAccessUtility.DISCOVERED_COMPONENTS, new HashMap<String, Base>());
            model.wrapModel(LEMSAccessUtility.DISCOVERED_LEMS_COMPONENTS, new HashMap<String, Object>());

            model.wrapModel(NeuroMLAccessUtility.DISCOVERED_NESTED_COMPONENTS_ID, new ArrayList<String>());
        } catch (IOException e) {
            throw new ModelInterpreterException(e);
        } catch (ContentError e) {
            throw new ModelInterpreterException(e);
        } catch (JAXBException e) {
            throw new ModelInterpreterException(e);
        } catch (Exception e) {
            throw new ModelInterpreterException(e);
        }
        return model;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.geppetto.core.model.IModelInterpreter#populateModelTree(org.geppetto.core.model.runtime.AspectNode)
     */
    @Override
    public boolean populateModelTree(AspectNode aspectNode) throws ModelInterpreterException {

        boolean modified = false;

        AspectSubTreeNode modelTree = (AspectSubTreeNode) aspectNode.getSubTree(AspectTreeType.MODEL_TREE);
        modelTree.setId(AspectTreeType.MODEL_TREE.toString());

        IModel model = aspectNode.getModel();
        try {
            NeuroMLDocument neuroml = (NeuroMLDocument) ((ModelWrapper) model)
                    .getModel(NeuroMLAccessUtility.NEUROML_ID);
            if (neuroml != null) {
                //            URL url = (URL) ((ModelWrapper) model).getModel(URL_ID);
                // Use local class to populate model tree
                modified = populateModelTree.populateModelTree(modelTree, ((ModelWrapper) model));
                modelTree.setModified(modified);
            }

        } catch (Exception e) {
            throw new ModelInterpreterException(e);
        }
        return modified;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.geppetto.core.model.IModelInterpreter#populateRuntimeTree(org.geppetto.core.model.runtime.AspectNode)
     */
    @Override
    public boolean populateRuntimeTree(AspectNode aspectNode) throws ModelInterpreterException {
        AspectSubTreeNode modelTree = (AspectSubTreeNode) aspectNode.getSubTree(AspectTreeType.MODEL_TREE);
        AspectSubTreeNode visualizationTree = (AspectSubTreeNode) aspectNode
                .getSubTree(AspectTreeType.VISUALIZATION_TREE);

        modelTree.setId(AspectTreeType.MODEL_TREE.toString());
        visualizationTree.setId(AspectTreeType.VISUALIZATION_TREE.toString());
        populateSubEntities(aspectNode);
        return true;
    }

    /**
     * @param aspectNode
     * @param _model
     * @throws ModelInterpreterException
     * @throws MalformedURLException
     * @throws JAXBException
     */
    /**
     * @param aspectNode
     * @throws ModelInterpreterException
     */
    private void populateSubEntities(AspectNode aspectNode) throws ModelInterpreterException {
        if (((ModelWrapper) aspectNode.getModel())
                .getModel(neuroMLAccessUtility.NEUROML_ID) instanceof NeuroMLDocument) {
            NeuroMLDocument neuroml = (NeuroMLDocument) ((ModelWrapper) aspectNode.getModel())
                    .getModel(neuroMLAccessUtility.NEUROML_ID);
            URL url = (URL) ((ModelWrapper) aspectNode.getModel()).getModel(neuroMLAccessUtility.URL_ID);

            List<Network> networks = neuroml.getNetwork();
            if (networks == null || networks.size() == 0) {
                // What do we do?
            } else if (networks.size() == 1) {
                // there's only one network, we consider the entity for it our network entity
                addNetworkSubEntities(networks.get(0), (EntityNode) aspectNode.getParentEntity(), url, aspectNode,
                        (ModelWrapper) aspectNode.getModel());
            } else if (networks.size() > 1) {
                // there's more than one network, each network will become an entity
                for (Network n : networks) {
                    EntityNode networkEntity = new EntityNode(n.getId());
                    addNetworkSubEntities(n, networkEntity, url, aspectNode, (ModelWrapper) aspectNode.getModel());
                    aspectNode.getChildren().add(networkEntity);
                }
            }
        }
    }

    /**
     * @param n
     * @param parentEntity
     * @param url
     * @param aspect
     * @param neuroml
     * @throws MalformedURLException
     * @throws JAXBException
     * @throws ModelInterpreterException
     * @throws ContentError 
     */
    private void addNetworkSubEntities(Network n, EntityNode parentEntity, URL url, AspectNode aspect,
            ModelWrapper model) throws ModelInterpreterException {
        if (n.getPopulation().size() == 1 && parentEntity.getId().equals(n.getPopulation().get(0).getComponent())
                && n.getPopulation().get(0).getSize().equals(BigInteger.ONE)) {
            // there's only one cell whose name is the same as the geppetto entity, don't create any subentities
            neuroMLAccessUtility.getComponent(n.getPopulation().get(0).getComponent(), model, Resources.CELL);
            mapCellIdToEntity(parentEntity.getId(), parentEntity, aspect);
            return;
        }
        for (Population p : n.getPopulation()) {
            //BaseCell cell = getCell(p, url, model);
            BaseCell cell = (BaseCell) neuroMLAccessUtility.getComponent(p.getComponent(), model, Resources.CELL);
            if (p.getType() != null && p.getType().equals(PopulationTypes.POPULATION_LIST)) {
                int i = 0;
                for (Instance instance : p.getInstance()) {
                    String id = VariablePathSerializer.getArrayName(p.getId(), i);
                    EntityNode e = getEntityNodefromCell(cell, id, aspect);

                    if (instance.getLocation() != null) {
                        e.setPosition(getPoint(instance.getLocation()));
                    }
                    e.setId(id);
                    parentEntity.addChild(e);
                    i++;
                }

            } else {
                int size = p.getSize().intValue();

                for (int i = 0; i < size; i++) {
                    // FIXME the position of the population within the network needs to be specified in neuroml
                    String id = VariablePathSerializer.getArrayName(cell.getId(), i);
                    EntityNode e = getEntityNodefromCell(cell, id, aspect);
                    e.setId(id);
                    parentEntity.addChild(e);
                }
            }
        }

    }

    /**
     * @param c
     * @param id
     * @param parentAspectNode
     * @return
     */
    private EntityNode getEntityNodefromCell(BaseCell c, String id, AspectNode parentAspectNode) {
        EntityNode entity = new EntityNode(id);
        AspectNode aspectNode = new AspectNode(parentAspectNode.getId());
        aspectNode.setParent(entity);
        aspectNode.setId(parentAspectNode.getId());
        entity.getAspects().add(aspectNode);
        AspectSubTreeNode modelTree = (AspectSubTreeNode) aspectNode.getSubTree(AspectTreeType.MODEL_TREE);
        AspectSubTreeNode visualizationTree = (AspectSubTreeNode) aspectNode
                .getSubTree(AspectTreeType.VISUALIZATION_TREE);
        modelTree.setId(AspectTreeType.MODEL_TREE.toString());
        visualizationTree.setId(AspectTreeType.VISUALIZATION_TREE.toString());
        mapCellIdToEntity(id, entity, parentAspectNode);
        return entity;
    }

    /**
     * @param cell
     * @param entity
     */
    private void mapCellIdToEntity(String id, EntityNode entity, AspectNode parentEntityAspect) {
        Map<String, EntityNode> mapping = (Map<String, EntityNode>) ((ModelWrapper) parentEntityAspect.getModel())
                .getModel(NeuroMLAccessUtility.SUBENTITIES_MAPPING_ID);
        mapping.put(id, entity);
    }

    /**
     * @param cell
     * @return
     */
    public static AspectSubTreeNode getSubEntityAspectSubTreeNode(BaseCell cell,
            AspectSubTreeNode.AspectTreeType type, AspectNode aspect, ModelWrapper model) {
        EntityNode entity = ((Map<BaseCell, EntityNode>) model
                .getModel(NeuroMLAccessUtility.SUBENTITIES_MAPPING_ID)).get(cell);
        for (AspectNode a : entity.getAspects()) {
            if (a.getId().equals(aspect.getId())) {
                return a.getSubTree(type);
            }
        }
        return null;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.geppetto.core.model.IModelInterpreter#getName()
     */
    @Override
    public String getName() {
        return this.neuroMLModelInterpreterConfig.getModelInterpreterName();
    }

    /**
     * @param location
     * @return
     */
    private Point getPoint(Location location) {
        Point point = new Point();
        point.setX(location.getX().doubleValue());
        point.setY(location.getY().doubleValue());
        point.setZ(location.getZ().doubleValue());
        return point;
    }

}