/* * 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 * */ package org.neugen.datastructures; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import java.util.Map; import javax.vecmath.Point3f; import org.apache.log4j.Logger; import org.neugen.datastructures.parameter.CommonTreeParam; /** * Base class for tree structures like dendrites and axons. * @author Alex Wanner * @author Sergei Wolf */ public class NeuronalTreeStructure<SectionType extends Section> implements Serializable { private static final long serialVersionUID = -3622226473283033478L; /** Use to log messages. */ private static final Logger logger = Logger.getLogger(NeuronalTreeStructure.class.getName()); protected SectionType firstSection; /** Pointer to the common tree parameter.*/ protected transient CommonTreeParam par; public SectionType getFirstSection() { return firstSection; } public void setFirstSection(SectionType section) { this.firstSection = section; } public int getNumOfSegments() { int numberOfSegments = 0; if (firstSection != null) { Section.Iterator secit = firstSection.getIterator(); while (secit.hasNext()) { Section section = secit.next(); numberOfSegments += section.getSegments().size(); } } return numberOfSegments; } public int getNumOfSections() { int numberOfSections = 0; if (firstSection != null) { Section.Iterator secit = firstSection.getIterator(); while (secit.hasNext()) { secit.next(); numberOfSections++; } } return numberOfSections; } /** * Get total length of neuronal tree structure. * * @return the length of neuronal tree structure. */ public float getTotalLength() { //logger.info("getLength begin"); float length = 0.0f; int numSec = 0; int numSeg = 0; if (firstSection != null) { Section.Iterator secit = firstSection.getIterator(); while (secit.hasNext()) { Section sec = secit.next(); numSec++; //logger.info("sec name: " + sec.getSectionName()); for (Segment segment : sec.getSegments()) { numSeg++; length += segment.getLength(); } } } /* logger.info("numSec: " + numSec); logger.info("numSeg: " + numSeg); logger.info("getLength end"); */ return length; } /** * Get total length of neuronal tree structure. * * @return the length of neuronal tree structure. */ public Point3f getRadius() { //logger.info("getLength begin"); float radius = 0.0f; float averageRadius = 0.0f; //float minRadius = 0.15f; float minRadius = 10.0f; float maxRadius = 0.0f; int numSec = 0; int numSeg = 0; if (firstSection != null) { Section.Iterator secit = firstSection.getIterator(); while (secit.hasNext()) { Section sec = secit.next(); numSec++; //logger.info("sec name: " + sec.getSectionName()); for (Segment segment : sec.getSegments()) { numSeg++; float sRad = segment.getStartRadius(); float eRad = segment.getEndRadius(); //length += segment.getLength(); radius = sRad; radius+= eRad; radius /=2.0f; averageRadius += radius; if(maxRadius < sRad) { maxRadius = sRad; } if(maxRadius < eRad) { maxRadius = eRad; } if(minRadius > sRad && sRad > 0.01f) { minRadius = sRad; } if(minRadius > eRad && eRad > 0.01f) { minRadius = eRad; } } } } if(averageRadius != 0.0f) { averageRadius /= (float)numSeg; } if(averageRadius == 0.0f && maxRadius == 0.0f) { minRadius = 0.0f; } /* logger.info("numSec: " + numSec); logger.info("numSeg: " + numSeg); logger.info("getLength end"); */ Point3f ret = new Point3f(maxRadius, minRadius, averageRadius); return ret; } public float getNTSVolume() { float volume = 0.0f; if (firstSection != null) { Section.Iterator secit = firstSection.getIterator(); while (secit.hasNext()) { Section curSec = secit.next(); for (Segment curSeg : curSec.getSegments()) { volume += curSeg.getVolume(); } } } return volume; } public void getNTSSize( Map<Integer, Pair<Float, Float>> xData, Map<Integer, Pair<Float, Float>> yData, Map<Integer, Pair<Float, Float>> zData ) { if (firstSection != null) { Section.Iterator secIter = firstSection.getIterator(); while (secIter.hasNext()) { Section curSec = secIter.next(); for (Segment curSeg : curSec.getSegments()) { List<Point3f> points = new ArrayList<Point3f>(); points.add(curSeg.getStart()); points.add(curSeg.getEnd()); points.add(curSeg.getCenter()); for (Point3f currentSegmentData : points) { // berechne die Breite. die maximale z-Strecke. { int xCoord = (int) currentSegmentData.x; float zCoord = currentSegmentData.z; if (xData.containsKey(xCoord)) { Pair<Float, Float> minMaxZCoord = xData.get(xCoord); float minZ = minMaxZCoord.first; float maxZ = minMaxZCoord.second; if (zCoord < minZ) { minZ = zCoord; minMaxZCoord.first = minZ; //logger.info("new min z"); } else if (zCoord > maxZ) { maxZ = zCoord; minMaxZCoord.second = maxZ; //logger.info("new max z"); } } else { xData.put(xCoord, new Pair<Float, Float>(zCoord, zCoord)); } } // berechen die Laenge. die maximale x-Strecke { int yCoord = (int) currentSegmentData.y; float xCoord = currentSegmentData.x; /* for(int i = -10; i <= 10; i++) { int locCoord = yCoord+i; if(yData.contains(locCoord)) { logger.info("y umgengscoordinaten in der tabelle"); } } * */ if (yData.containsKey(yCoord)) { Pair<Float, Float> minMaxXCoord = yData.get(yCoord); float minX = minMaxXCoord.first; float maxX = minMaxXCoord.second; if (xCoord < minX) { minX = xCoord; minMaxXCoord.first = minX; //logger.info("new min x"); } else if (xCoord > maxX) { maxX = xCoord; minMaxXCoord.second = maxX; //logger.info("new max x"); } //yData.put(yCoord, minMaxXCoord); //logger.info("y ist in der tabelle"); } else { yData.put(yCoord, new Pair<Float, Float>(xCoord, xCoord)); } } // berechen die Hoehe. die maximale y-Strecke { int zCoord = (int) currentSegmentData.z; float yCoord = currentSegmentData.y; /* for(int i = -10; i <= 10; i++) { int locCoord = yCoord+i; if(yData.contains(locCoord)) { logger.info("y umgengscoordinaten in der tabelle"); } } * */ if (zData.containsKey(zCoord)) { Pair<Float, Float> minMaxXCoord = zData.get(zCoord); float minY = minMaxXCoord.first; float maxY = minMaxXCoord.second; if (yCoord < minY) { minY = yCoord; minMaxXCoord.first = minY; //logger.info("new min x"); } else if (yCoord > maxY) { maxY = yCoord; minMaxXCoord.second = maxY; //logger.info("new max x"); } //yData.put(yCoord, minMaxXCoord); //logger.info("y ist in der tabelle"); } else { zData.put(zCoord, new Pair<Float, Float>(yCoord, yCoord)); } } } } } } } /** * Get surface area of neuronal tree structure. * * @return The surface are of neuronal tree structure. */ public float getSurfaceArea() { float area = 0.0f; if (firstSection != null) { Section.Iterator secit = firstSection.getIterator(); while (secit.hasNext()) { Section sec = secit.next(); for (Segment segment : sec.getSegments()) { area += segment.getSurfaceArea(); } } } return area; } /** * Get number of compartments of neuronal tree structure. * * @return The number of compartments neuronal tree structure. */ public int getNParts() { int nsegs = 0; if (firstSection != null) { Section.Iterator secit = firstSection.getIterator(); while (secit.hasNext()) { Section sec = secit.next(); nsegs += sec.getSegments().size(); } } return nsegs; } public int getNBranch() { int ret = 0; if (firstSection != null) { Section.Iterator secit = firstSection.getIterator(); while (secit.hasNext()) { Section sec = secit.next(); if (sec.getChildrenLink() != null) { if (sec.getChildrenLink().getBranch0() != null && sec.getChildrenLink().getBranch1() != null) { ret++; } } } } return ret; } /** * Get the relevant data of the dendrite section where the compartment * with index cd_idx lies within the given section. * @param sec_id The section Id. * @param cd_idx The index of the segment. * @return The relative position of the segment within the section sec_id. */ public float getDendriteSectionData(int sec_id, int cd_idx) { float dd = 0.0f; float len = 0.0f; float ret = 0.0f; if (firstSection != null) { Section.Iterator secit = firstSection.getIterator(); Section sec = secit.get(sec_id); //logger.info("section with sec_id found: " + sec.getName()); for (Segment segment : sec.getSegments()) { len += segment.getLength(); } for (int i = 0; !(i > cd_idx); ++i) { dd += sec.getSegments().get(i).getLength(); } ret = dd / len; } return ret; } /** * Get the relevant data of the dendrite section where the compartment * with index cd_idx lies within the given section. * @param sec_id The section Id. * @param cd_idx The index of the segment. * @return The relative position of the segment within the section sec_id. */ public static float getDendriteSectionData(Section sec, int cd_idx) { float dd = 0.0f; float len = 0.0f; //logger.info("section with sec_id found: " + sec.getName()); for (Segment segment : sec.getSegments()) { len += segment.getLength(); } for (int i = 0; !(i > cd_idx); ++i) { dd += sec.getSegments().get(i).getLength(); } float ret = dd / len; return ret; } }