/* * Copyright (c) 2005–2012 Goethe Center for Scientific Computing - Simulation and Modelling (G-CSC Frankfurt) * Copyright (c) 2012-2015 Goethe Center for Scientific Computing - Computational Neuroscience (G-CSC Frankfurt) * * This file is part of NeuGen. * * NeuGen is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * as published by the Free Software Foundation. * * see: http://opensource.org/licenses/LGPL-3.0 * file://path/to/NeuGen/LICENSE * * NeuGen is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * This version of NeuGen includes copyright notice and attribution requirements. * According to the LGPL this information must be displayed even if you modify * the source code of NeuGen. The copyright statement/attribution may not be removed. * * Attribution Requirements: * * If you create derived work you must do the following regarding copyright * notice and author attribution. * * Add an additional notice, stating that you modified NeuGen. In addition * you must cite the publications listed below. A suitable notice might read * "NeuGen source code modified by YourName 2012". * * Note, that these requirements are in full accordance with the LGPL v3 * (see 7. Additional Terms, b). * * Publications: * * S. Wolf, S. Grein, G. Queisser. NeuGen 2.0 - * Employing NeuGen 2.0 to automatically generate realistic * morphologies of hippocapal neurons and neural networks in 3D. * Neuroinformatics, 2013, 11(2), pp. 137-148, doi: 10.1007/s12021-012-9170-1 * * * J. P. Eberhard, A. Wanner, G. Wittum. NeuGen - * A tool for the generation of realistic morphology * of cortical neurons and neural networks in 3D. * Neurocomputing, 70(1-3), pp. 327-343, doi: 10.1016/j.neucom.2006.01.028 * */ /* * Dendrite.java * * created on 19.03.2004 * */ package org.neugen.datastructures; import org.neugen.datastructures.parameter.ConstrParameter; import java.io.Serializable; import javax.vecmath.Point3f; import javax.vecmath.Vector3f; import org.apache.log4j.Logger; import org.neugen.utils.Vrand; import org.neugen.datastructures.parameter.CommonTreeParam; import org.neugen.datastructures.parameter.DendriteParam; import org.neugen.datastructures.parameter.DendriteParam.ApicalParam; import org.neugen.datastructures.parameter.DendriteParam.BasalParam; /** * It contains the basic class for the construction of a single dendrite. * The dendrite can have several branches where the forks are installed. The branches can be * basal, pyramidal, or oblique branches. * * @author Jens Eberhard */ public class Dendrite extends NeuronalTreeStructure<DendriteSection> implements Serializable { private static final long serialVersionUID = -4611546473283433478L; /** use to log messages */ private final static Logger logger = Logger.getLogger(Dendrite.class.getName()); /** random number generator */ private transient Vrand drawNumber; /** Pointer to dendrite parameter */ public transient CommonTreeParam denPar; public Dendrite() { super(); firstSection = new DendriteSection(); } public void setDrawNumber(Vrand drawNumber) { this.drawNumber = drawNumber; } /** * Set basal dendrites of interneuron */ public void setHorizontalBasalDendrite(BasalParam param, Cellipsoid soma, Vector3f deviation, float scale, boolean down, boolean horizontalDir) { logger.info("set horizontal basal dendrit!!!"); drawNumber.setRotDeviation(deviation); denPar = param; ConstrParameter cp = new ConstrParameter(); cp.drawNumber = drawNumber; cp.sectionTye = DendriteSection.SectionType.BASAL; cp.branchDistribution = null; cp.branchLevel = 0; //cp.deviation = new Vector3f(deviation); cp.startRadius = param.getRad().getMax().floatValue(); cp.endRadius = param.getRad().getMin().floatValue(); cp.minRadius = param.getRad().getMin().floatValue(); cp.genNumberSegments = 1; cp.generationParam = param.getFirstGen(); cp.parentSection = null; cp.soma = soma; // unter dem soma! int up_down = -1; cp.sectionStartPoint = new Point3f(soma.getMid()); cp.sectionStartPoint.z += up_down * soma.getMaxRadius(); cp.sectionEndPoint = new Point3f(soma.getMid()); /* cp.end.x += param.getFirstGen().getLenParam().getX(); cp.end.y += param.getFirstGen().getLenParam().getY(); cp.end.z += down * param.getFirstGen().getLenParam().getZ(); * */ cp.obliqueParam = null; cp.numberOblique = 0; cp.maxZ = Region.getInstance().getUpRightCorner().z; //logger.info("max z Wert: " + cp.maxZ); cp.a = param.getA(); cp.c = param.getC(); cp.id = 0; cp.horizontalDir = true; boolean respectColumn = false; boolean automaticShortening = false; float lowBranchingLimit = param.getLowBranchingLimit().getValue(); if(down) { lowBranchingLimit = 0.0f; } firstSection = new DendriteSection(new ConstrParameter(cp), respectColumn, scale, automaticShortening, down, lowBranchingLimit); //logger.info("first sec lenght: " + firstSection.getLength()); if (firstSection.getChildrenLink() != null) { //logger.info("update poly soma dist!"); firstSection.getChildrenLink().updatePolySomaDist(); } } /** * Set an pyramidal basal dendrite (CA1) */ public void setBasalDendrite(BasalParam param, Cellipsoid soma, Vector3f deviation, float scale, boolean down) { drawNumber.setRotDeviation(deviation); denPar = param; ConstrParameter cp = new ConstrParameter(); cp.drawNumber = drawNumber; cp.sectionTye = DendriteSection.SectionType.BASAL; cp.branchDistribution = null; cp.branchLevel = 0; //cp.deviation = new Vector3f(deviation); cp.startRadius = param.getRad().getMax().floatValue(); cp.endRadius = param.getRad().getMin().floatValue(); cp.minRadius = param.getRad().getMin().floatValue(); cp.genNumberSegments = 1; cp.generationParam = param.getFirstGen(); cp.parentSection = null; cp.soma = soma; // unter dem soma! int up_down = -1; cp.sectionStartPoint = new Point3f(soma.getMid()); cp.sectionStartPoint.z += up_down * soma.getMaxRadius(); cp.sectionEndPoint = new Point3f(soma.getMid()); /* cp.end.x += param.getFirstGen().getLenParam().getX(); cp.end.y += param.getFirstGen().getLenParam().getY(); cp.end.z += down * param.getFirstGen().getLenParam().getZ(); * */ cp.obliqueParam = null; cp.numberOblique = 0; cp.maxZ = Region.getInstance().getUpRightCorner().z; //logger.info("max z Wert: " + cp.maxZ); cp.a = param.getA(); cp.c = param.getC(); cp.id = 0; boolean respectColumn = false; boolean automaticShortening = false; float lowBranchingLimit = param.getLowBranchingLimit().getValue(); if(down) { lowBranchingLimit = 0.0f; } firstSection = new DendriteSection(new ConstrParameter(cp), respectColumn, scale, automaticShortening, down, lowBranchingLimit); //logger.info("first sec lenght: " + firstSection.getLength()); if (firstSection.getChildrenLink() != null) { //logger.info("update poly soma dist!"); firstSection.getChildrenLink().updatePolySomaDist(); } } /** * Set an usual dendrite. It creates the list of compartments. * @param param dendrite parameter. * @param soma the soma of the neuron. * @param deviation the deviation vector for the compartments of dendrite. * @param respectColumns says to respect column limits.? */ public void setDendrite(DendriteParam param, Cellipsoid soma, Vector3f deviation, boolean respectColumns) { drawNumber.setRotDeviation(deviation); denPar = param; ConstrParameter cp = new ConstrParameter(); cp.drawNumber = drawNumber; cp.sectionTye = DendriteSection.SectionType.BASAL; cp.branchDistribution = null; cp.branchLevel = 0; //cp.deviation = new Vector3f(deviation); cp.sectionEndPoint = new Point3f(); cp.startRadius = param.getRad().getMax().floatValue(); cp.endRadius = param.getRad().getMin().floatValue(); cp.minRadius = param.getRad().getMin().floatValue(); //logger.info("max radius of dendrite: " + cp.startRadius); //logger.info("min radius of dendrite: " + cp.endRadius); cp.genNumberSegments = 1; cp.generationParam = param.getFirstGen(); cp.parentSection = null; cp.soma = soma; cp.sectionStartPoint = new Point3f(soma.getMid()); cp.sectionStartPoint.z += soma.getMeanRadius(); cp.obliqueParam = null; cp.numberOblique = 0; cp.maxZ = Region.getInstance().getUpRightCorner().z; cp.a = param.getA(); cp.c = param.getC(); cp.id = 0; //logger.info("max angle: " + param.getFirstGen().getBranchAngle().getMax()); //logger.info("min angle: " + param.getFirstGen().getBranchAngle().getMin()); //logger.info("setDendrite randomNum(orig): " + drawNumber.draw()); //logger.info("setDendrite randomNum(cp): " + cp.drawNumber.draw()); //logger.info("random number counter: " + draw_number.getRandNumCounter()); firstSection = new DendriteSection(new ConstrParameter(cp), respectColumns, 1.0f, false); if (firstSection.getChildrenLink() != null) { firstSection.getChildrenLink().updatePolySomaDist(); } } /** * Set an apical pyramidal dendrite. It creates the list of compartments. * @param soma the soma of the neuron. * @param deviation the deviation vector for the compartments of the pyramidal end of dendrite. * @param numObliqueBranch apical_continuations the number of oblique branches for */ public void setPyramidalDendrite(ApicalParam param, Cellipsoid soma, Vector3f deviation, int numObliqueBranch) { drawNumber.setRotDeviation(deviation); denPar = param; ConstrParameter cp = new ConstrParameter(); cp.drawNumber = drawNumber; cp.sectionTye = DendriteSection.SectionType.APICAL; cp.branchDistribution = null; cp.branchLevel = 0; //cp.deviation = deviation; cp.sectionEndPoint = new Point3f(); cp.startRadius = param.getRad().getMax(); cp.endRadius = param.getRad().getMin(); cp.minRadius = param.getRad().getMin(); cp.genNumberSegments = 1; cp.generationParam = param.getFirstGen(); cp.parentSection = null; cp.soma = soma; cp.sectionStartPoint = new Point3f(soma.getMid()); cp.sectionStartPoint.z += soma.getMeanRadius(); cp.obliqueParam = param.getOblique(); cp.numberOblique = numObliqueBranch; cp.a = param.getA(); cp.c = param.getC(); cp.id = 0; if (!param.getFirstGen().getLenParam().isValid()) { cp.maxZ = Region.getInstance().getUpRightCorner().z; } else { cp.maxZ = param.getFirstGen().getLenParam().getZ() * (1 + param.getTopFluctuationValue() * (2 * drawNumber.fdraw() - 1)) + soma.getMid().z; if (cp.maxZ > Region.getInstance().getUpRightCorner().z) { cp.maxZ = Region.getInstance().getUpRightCorner().z; } } if (!param.getLowBranchingLimit().isValid()) { firstSection = new DendriteSection(new ConstrParameter(cp), 0.0f); } else { logger.info("create dendrite section with low branching limit: " + param.getLowBranchingLimit().getValue()); firstSection = new DendriteSection(new ConstrParameter(cp), param.getLowBranchingLimit().getValue()); } if (firstSection.getChildrenLink() != null) { firstSection.getChildrenLink().updatePolySomaDist(); } } }