/* * 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 org.neugen.datastructures.neuron.NeuronL5APyramidal; import org.neugen.datastructures.neuron.NeuronL5BPyramidal; import org.neugen.datastructures.neuron.NeuronStarpyramidal; import org.neugen.datastructures.neuron.NeuronL4stellate; import org.neugen.datastructures.neuron.Neuron; import org.neugen.datastructures.neuron.NeuronL23Pyramidal; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.Serializable; import java.io.Writer; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import javax.vecmath.Point3f; import org.apache.log4j.Logger; import org.neugen.datastructures.neuron.NeuronBase; import org.neugen.utils.Frand; import org.neugen.gui.NeuGenLibTask; import org.neugen.datastructures.parameter.NetParam; import org.neugen.gui.NeuGenConstants; import org.neugen.gui.NeuGenView; import org.neugen.gui.Trigger; /** * @author Jens Eberhard * @author Simone Eberhard * @author Alexander Wanner * @author Sergei Wolf */ public final class NetNeocortex extends NetBase implements Serializable, Net { private static final long serialVersionUID = -7041930070394524614L; /** use to log messages */ private final static Logger logger = Logger.getLogger(NetNeocortex.class.getName()); //neocortex data public static final int cellTypesNumber = 5; private int nL4stellate; private int npyramidal; private int nL23pyramidal; private int nL5pyramidal; private int nL5Apyramidal; private int nL5Bpyramidal; private int nstarpyramidal; public NetNeocortex() { super(); region.setColumnSize(); netParam = NetParam.getInstance(); setDrawNumber(new Frand(netParam.getSeedValue())); nL4stellate = netParam.getNumL4stellate(); nL23pyramidal = netParam.getNumL23pyramidal(); nL5Apyramidal = netParam.getNumL5Apyramidal(); nL5Bpyramidal = netParam.getNumL5Bpyramidal(); nstarpyramidal = netParam.getNumStarpyramidal(); nL5pyramidal = nL5Apyramidal + nL5Bpyramidal; npyramidal = nL23pyramidal + nL5pyramidal; nneuron = nL4stellate + npyramidal + nstarpyramidal; synNumbers = new long[cellTypesNumber][cellTypesNumber]; typeCellNames.clear(); typeCellNames.add(DataStructureConstants.L4_STELLATE); typeCellNames.add(DataStructureConstants.L23_PYRAMIDAL); typeCellNames.add(DataStructureConstants.L5A_PYRAMIDAL); typeCellNames.add(DataStructureConstants.L5B_PYRAMIDAL); typeCellNames.add(DataStructureConstants.STAR_PYRAMIDAL); typeCellNumbers = new int[cellTypesNumber]; reInitTypeCellNumbers(); cellOffsets = new int[6]; cellOffsets[0] = 0; reInitCellOffsets(); } public void reInitCellOffsets() { cellOffsets[1] = nL4stellate; cellOffsets[2] = cellOffsets[1] + nL23pyramidal; cellOffsets[3] = cellOffsets[2] + nL5Apyramidal; cellOffsets[4] = cellOffsets[3] + nL5Bpyramidal; cellOffsets[5] = cellOffsets[4] + nstarpyramidal; } public void reInitTypeCellNumbers() { typeCellNumbers[0] = nL4stellate; typeCellNumbers[1] = nL23pyramidal; typeCellNumbers[2] = nL5Apyramidal; typeCellNumbers[3] = nL5Bpyramidal; typeCellNumbers[4] = nstarpyramidal; } public enum NeuronTypes { L4_STELLATE(1), L23_PYRAMIDAL(2), L5A_PYRAMIDAL(3), L5B_PYRAMIDAL(4), L4_STAR_PYRAMIDAL(5); private int num; public int getNum() { return num; } NeuronTypes(int num) { this.num = num; } } @Override public void generate() { NeuGenLibTask ngLibTask = NeuGenLibTask.getInstance(); Region.Param.ColumnParam columnPar = Region.Param.getInstance().getColumnParam(); float lengthX = columnPar.getLength(); float widthY = columnPar.getWidth(); float heightZ = columnPar.getHeight(); float layer1Height = columnPar.getLayer1(); float layer23Height = columnPar.getLayer23(); float layer4Height = columnPar.getLayer4(); float layer5AHeight = columnPar.getLayer5A(); float layer5BHeight = columnPar.getLayer5B(); float layer6Height = columnPar.getLayer6(); nnf_synapses = 0; if (!neuronList.isEmpty()) { neuronList.clear(); } NeuronBase.setDrawNumber(null); int i = 0; if (nL4stellate > 0) { NeuronL4stellate.deleteData(); logger.info("generate " + nL4stellate + " L4stellate neurons"); float l4start = layer6Height + layer5BHeight + layer5AHeight; float somaRad = NeuronL4stellate.Param.getInstance().getSomaParam().getRadValue(); if (layer4Height > 0 && layer1Height > somaRad) { for (; i < cellOffsets[1]; ++i) { Neuron l4Stellate = new NeuronL4stellate(); l4Stellate.setIndex(i); /* if(testSomaCollision(l4Stellate, somaMid, somaRad)) { somaMid.x = lengthX * drawNumber.fdraw(); somaMid.y = widthY * drawNumber.fdraw(); somaMid.z = l4start + 50.0f + 100.0f * drawNumber.fdraw(); } if(testSomaCollision(l4Stellate, somaMid, somaRad)) { trigger.outPrintln("zelle verwerfen!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); this.nL4stellate--; continue; } */ Point3f somaMid = new Point3f(); if (nL4stellate == 1) { somaMid.x = lengthX / 2.0f + drawNumber.fpm_onedraw() * lengthX / 10.0f; somaMid.y = widthY / 2.0f + drawNumber.fpm_onedraw() * widthY / 10.0f; } else { somaMid.x = lengthX * drawNumber.fdraw(); somaMid.y = widthY * drawNumber.fdraw(); } somaMid.z = l4start + layer4Height / 2.0f * drawNumber.fdraw(); l4Stellate.setSoma(somaMid, somaRad); l4Stellate.setNeuron(); l4Stellate.infoNeuron(); neuronList.add(i, l4Stellate); if (ngLibTask != null) { ngLibTask.setMyProgress((0.1f + ((float) i + 1)) / nneuron * 0.1f); } } } else { nL4stellate = 0; } } if (nL23pyramidal > 0) { logger.info("generate " + nL23pyramidal + " L23pyramidal neurons"); NeuronL23Pyramidal.deleteData(); float l23start = layer6Height + layer5BHeight + layer5AHeight + layer4Height; float somaRad = NeuronL23Pyramidal.Param.getInstance().getSomaParam().getRadValue(); if (layer23Height > 0 && layer23Height > somaRad) { for (; i < cellOffsets[2]; ++i) { Neuron l23Pyramidal = new NeuronL23Pyramidal(); l23Pyramidal.setIndex(i); //testSomaCollision(l23Pyramidal, somaMid, somaRad); Point3f somaMid = new Point3f(); if (nL23pyramidal == 1) { somaMid.x = lengthX / 2.0f + drawNumber.fpm_onedraw() * lengthX / 10.0f; somaMid.y = widthY / 2.0f + drawNumber.fpm_onedraw() * widthY / 10.0f; } else { somaMid.x = lengthX * drawNumber.fdraw(); somaMid.y = widthY * drawNumber.fdraw(); } somaMid.z = l23start + layer23Height / 2.0f * drawNumber.fdraw(); l23Pyramidal.setSoma(somaMid, somaRad); l23Pyramidal.setNeuron(); l23Pyramidal.infoNeuron(); neuronList.add(i, l23Pyramidal); if (ngLibTask != null) { ngLibTask.setMyProgress((0.1f + ((float) i + 1)) / nneuron * 0.1f); } } } else { nL23pyramidal = 0; } } if (nL5Apyramidal > 0) { NeuronL5APyramidal.deleteData(); logger.info("generate " + nL5Apyramidal + " L5Apyramidal neurons"); float l5Astart = layer6Height + layer5BHeight; float somaRad = NeuronL5APyramidal.Param.getInstance().getSomaParam().getRadValue(); if (layer5AHeight > 0 && layer5AHeight > somaRad) { for (; i < cellOffsets[3]; ++i) { Neuron l5APyramidal = new NeuronL5APyramidal(); l5APyramidal.setIndex(i); //testSomaCollision(l5APyramidal, somaMid, somaRad); //l5APyramidal.setSoma(somaMid, somaRad); Point3f somaMid = new Point3f(); if (nL5Apyramidal == 1) { somaMid.x = lengthX / 2.0f + drawNumber.fpm_onedraw() * lengthX / 10.0f; somaMid.y = widthY / 2.0f + drawNumber.fpm_onedraw() * widthY / 10.0f; } else { somaMid.x = lengthX * drawNumber.fdraw(); somaMid.y = widthY * drawNumber.fdraw(); } somaMid.z = l5Astart + layer5AHeight / 2.0f * drawNumber.fdraw(); l5APyramidal.setSoma(somaMid, somaRad); l5APyramidal.setNeuron(); l5APyramidal.infoNeuron(); neuronList.add(i, l5APyramidal); if (ngLibTask != null) { ngLibTask.setMyProgress((0.1f + ((float) i + 1)) / nneuron * 0.1f); } } } else { nL5Apyramidal = 0; } } if (nL5Bpyramidal > 0) { NeuronL5BPyramidal.deleteData(); logger.info("generate " + nL5Bpyramidal + " L5Bpyramidal neurons"); float l5Bstart = layer6Height; //Point3f somaMid = new Point3f(lengthX / 2.0f, widthY / 2.0f, 500.0f); float somaRad = NeuronL5BPyramidal.Param.getInstance().getSomaParam().getRadValue(); if (layer5BHeight > 0 && layer5BHeight > somaRad) { for (; i < cellOffsets[4]; ++i) { Neuron l5BPyramidal = new NeuronL5BPyramidal(); l5BPyramidal.setIndex(i); //testSomaCollision(l5BPyramidal, somaMid, somaRad); Point3f somaMid = new Point3f(); if (nL5Bpyramidal == 1) { somaMid.x = lengthX / 2.0f + drawNumber.fpm_onedraw() * lengthX / 10.0f; somaMid.y = widthY / 2.0f + drawNumber.fpm_onedraw() * widthY / 10.0f; } else { somaMid.x = lengthX * drawNumber.fdraw(); somaMid.y = widthY * drawNumber.fdraw(); } somaMid.z = l5Bstart + layer5BHeight / 2.0f * drawNumber.fdraw(); l5BPyramidal.setSoma(somaMid, somaRad); l5BPyramidal.setNeuron(); l5BPyramidal.infoNeuron(); neuronList.add(i, l5BPyramidal); if (ngLibTask != null) { ngLibTask.setMyProgress((0.1f + ((float) i + 1)) / nneuron * 0.1f); } } } else { nL5Bpyramidal = 0; } } if (nstarpyramidal > 0) { NeuronStarpyramidal.deleteData(); logger.info("generate " + nstarpyramidal + " starpyramidal neurons"); float l4start = layer6Height + layer5BHeight + layer5AHeight; for (; i < cellOffsets[5]; ++i) { Neuron starPyramidal = new NeuronStarpyramidal(); starPyramidal.setIndex(i); float somaRad = NeuronStarpyramidal.Param.getInstance().getSomaParam().getRadValue(); //testSomaCollision(starPyramidal, somaMid, somaRad); Point3f somaMid = new Point3f(); if (nstarpyramidal == 1) { somaMid.x = lengthX / 2.0f + drawNumber.fpm_onedraw() * lengthX / 10.0f; somaMid.y = widthY / 2.0f + drawNumber.fpm_onedraw() * widthY / 10.0f; } else { somaMid.x = lengthX * drawNumber.fdraw(); somaMid.y = widthY * drawNumber.fdraw(); } somaMid.z = l4start + layer4Height / 2.0f * drawNumber.fdraw(); starPyramidal.setSoma(somaMid, somaRad); starPyramidal.setNeuron(); starPyramidal.infoNeuron(); neuronList.add(i, starPyramidal); if (ngLibTask != null) { ngLibTask.setMyProgress((0.1f + ((float) i + 1)) / nneuron * 0.1f); } } } setTotalNumOfSegments(); } public boolean testSomaCollision(Neuron target, Point3f somaMid, float somaRad) { for (Neuron curNeuro : neuronList) { boolean collide = curNeuro.getSoma().collide(somaMid, somaRad); if (collide) { //curNeuro.setCollide(collide); //target.setCollide(collide); logger.info("collide is true"); return true; } } return false; } /** * Function for interconnecting the net for a cortical column. * It connects the neurons with each other * and computes the number of synapses. */ @Override public void interconnect() { Trigger trigger = Trigger.getInstance(); trigger.outPrintln("interconnect neurons"); trigger.outPrintln("interconnect-phase"); trigger.outPrintln("interconnect"); NetParam netParameter = NetParam.getInstance(); float distSynapse = netParameter.getDistSynapse(); EpsilonDB sdbL4Stel = new EpsilonDB(distSynapse); EpsilonDB sdbL23Pyr = new EpsilonDB(distSynapse); EpsilonDB sdbL5A = new EpsilonDB(distSynapse); EpsilonDB sdbL5B = new EpsilonDB(distSynapse); EpsilonDB sdbStar = new EpsilonDB(distSynapse); int i = 0; for (i = 0; i < nL4stellate; ++i) { Neuron n = neuronList.get(i); Section.Iterator secIter = n.getAxon().getFirstSection().getIterator(); while (secIter.hasNext()) { Section section = secIter.next(); for (Segment segment : section.getSegments()) { sdbL4Stel.insert(new AxonSegmentData(n, section, segment)); } } } for (; i < nL4stellate + nL23pyramidal; ++i) { Neuron n = neuronList.get(i); Section.Iterator secIter = n.getAxon().getFirstSection().getIterator(); while (secIter.hasNext()) { Section section = secIter.next(); for (Segment segment : section.getSegments()) { sdbL23Pyr.insert(new AxonSegmentData(n, section, segment)); } } } for (; i < nL4stellate + nL23pyramidal + nL5Apyramidal; ++i) { Neuron n = neuronList.get(i); Section.Iterator secIter = n.getAxon().getFirstSection().getIterator(); while (secIter.hasNext()) { Section section = secIter.next(); for (Segment segment : section.getSegments()) { sdbL5A.insert(new AxonSegmentData(n, section, segment)); } } } for (; i < nL4stellate + npyramidal; ++i) { Neuron n = neuronList.get(i); Section.Iterator secIter = n.getAxon().getFirstSection().getIterator(); while (secIter.hasNext()) { Section section = secIter.next(); for (Segment segment : section.getSegments()) { sdbL5B.insert(new AxonSegmentData(n, section, segment)); } } } for (; i < nL4stellate + npyramidal + nstarpyramidal; i++) { Neuron n = neuronList.get(i); Section.Iterator secIter = n.getAxon().getFirstSection().getIterator(); while (secIter.hasNext()) { Section section = secIter.next(); for (Segment segment : section.getSegments()) { sdbStar.insert(new AxonSegmentData(n, section, segment)); } } } int[][] connectionMatrix = { {1, 1, 1, 0, 1}, {0, 1, 1, 1, 1}, {0, 1, 1, 0, 1}, {0, 0, 0, 1, 1}, {1, 1, 1, 1, 1} }; NeuGenLibTask ngLibTask = NeuGenLibTask.getInstance(); float progress = 0; if (ngLibTask != null) { progress = ngLibTask.getProgress(); progress /= 100.0f; ngLibTask.setMyProgress(progress); } int[] limits = {nL4stellate, nL23pyramidal, nL5Apyramidal, nL5Bpyramidal, nstarpyramidal}; EpsilonDB[] dbs = {sdbL4Stel, sdbL23Pyr, sdbL5A, sdbL5B, sdbStar}; int begin = 0; //logger.info("1. for Schleife: durchlaufe alle Zellentypen: " + cellTypesNumber); // laufe ueber alle zellentypen durch for (int c = 0; c < cellTypesNumber; c++) { if (ngLibTask != null) { progress = 0; float tmp = ((float) (c + 1) / (float) cellTypesNumber); progress += tmp; if (progress >= 1.0f) { progress = 0.9f; } ngLibTask.setMyProgress(progress); } //long[][] localSynNumbers = new long[cellTypesNumber][cellTypesNumber]; long localNsynapse = 0; int limitsSize = limits[c] + begin; /* logger.info("limits[c]: " + limits[c]); logger.info("begin: " + begin); logger.info("limits_size: " + limits_size); */ //logger.info("2. for Schleife: durchlaufe alle Neurone diese Typen"); for (int ii = begin; ii < limitsSize; ii++) { Neuron neuron = neuronList.get(ii); //logger.info("3. for Schleife: durchlaufe alle Dendriten des Neurons: " + neuron.getDenList().size()); for (Dendrite currentDendrite : neuron.getDendrites()) { Section.Iterator secIter = currentDendrite.getFirstSection().getIterator(); //logger.info("secion name:" + den_j.getFirstSection().getSectionName()); ///< loop over all section of dendrite j of neuron2 // while (sectionIterator.hasNext()) { //logger.info("while Schleife: Durchlaufe alle Sektionen des Dendrites"); while (secIter.hasNext()) { Section denSection = secIter.next(); //section = sectionIterator.next(); //logger.info("section id: " + section.getSectionId()); //logger.info("secion name:" + section.getSectionName()); //logger.info("for Schleife: durchlaufe alle Segmente der Sektion: nsegs: " + nsegs); for (Segment denSegment : denSection.getSegments()) { Point3f end = denSegment.getEnd(); //logger.info("den_seg end: " + (int) v2[0] + " " + (int) v2[1] + " " + (int) v2[2]); // loop over all relevant dbs //logger.info("for Schleifen: durchlaufe die relevante Datenbank für jeden Segment"); for (int l = 0; l < cellTypesNumber; l++) { if (connectionMatrix[l][c] == 1) { //logger.info("rufe get epsilon env auf!"); List<AxonSegmentData> pAxSeg = dbs[l].getEpsilonEnv(end); for (int m = 0; m < pAxSeg.size(); m++) { if (pAxSeg.get(m).neuron.getIndex() != ii) { synNumbers[l][c]++; AxonSegmentData dbRec = pAxSeg.get(m); Cons co = new Cons.Builder(dbRec.segment, denSegment).neuron1(dbRec.neuron).neuron1AxSection(dbRec.section). neuron2(neuron).neuron2DenSection(denSection).build(); calculateSomaticDistance(co); synapseList.add(co); denSegment.has_ds_synapse(true); dbRec.getSegment().has_ds_synapse(true); localNsynapse++; } } } } } } } } begin += limits[c]; nsynapse += localNsynapse; } // alle Zellentypen durchgelaufen if (ngLibTask != null) { ngLibTask.setMyProgress(1.0f); } trigger.outPrintln("end of interconnect"); } public int getNumL23pyramidal() { return nL23pyramidal; } public int getNumL4stellate() { return nL4stellate; } public int getNumL5Apyramidal() { return nL5Apyramidal; } public int getNumL5Bpyramidal() { return nL5Bpyramidal; } public int getNumL5pyramidal() { return nL5pyramidal; } public int getNumPyramidal() { return npyramidal; } @Override public Map<String, Float> computeAPSN() { int[][] preSynNumbers = new int[cellTypesNumber][cellTypesNumber]; Neuron currentNeuron = null; Set<Neuron> neurons = new HashSet<Neuron>(); // Iterate over the synapses. for (Cons con : synapseList) { if (con.getNeuron1() == null) { continue; } if (currentNeuron == null) { currentNeuron = con.getNeuron2(); neurons.add(con.getNeuron1()); } else { if (con.getNeuron2().getIndex() != currentNeuron.getIndex()) { // Iterate over presynaptic sides // which are sorted in ascending order due to using set for (Neuron neuron_j : neurons) { int tPre = getTypeOfNeuron(neuron_j.getIndex()); int tPost = getTypeOfNeuron(currentNeuron.getIndex()); preSynNumbers[tPre - 1][tPost - 1]++; } currentNeuron = con.getNeuron2(); neurons.clear(); } neurons.add(con.getNeuron1()); } } //logger.info("neurons size: " + neurons.size()); // Iterate over presynaptic sides // which are sorted in ascending order due to using set for (Neuron neuron_j : neurons) { int tPre = getTypeOfNeuron(neuron_j.getIndex()); //logger.info("j:" + j); //logger.info("tPre: " + tPre); //logger.info("currentNeuron: " + currentNeuron); int tPost = getTypeOfNeuron(currentNeuron.getIndex()); //logger.info("tPost: " + tPost); preSynNumbers[tPre - 1][tPost - 1]++; } Map<String, Float> ret = new HashMap<String, Float>(); for (int i = 0; i < cellTypesNumber; i++) { for (int j = 0; j < cellTypesNumber; j++) { String key = (typeCellNames.get(i) + "->") + typeCellNames.get(j); //logger.info("key: " + key); //logger.info("j: " + j + " ,typeCellNumbers[j]: " + typeCellNumbers[j]); if (typeCellNumbers[j] != 0) { float val = (float) preSynNumbers[i][j] / typeCellNumbers[j]; ret.put(key, val); } } } return ret; } /** * Function to get the type of a neuron from its index in neuron_list, * 1=L2/3, 2=L4, 3=L5A, 4=L5B, 5=star (simone) */ @Override public int getTypeOfNeuron(int indexOfNeuron) { int typeOfNeuron = -1; //order of indices of neurons in neuron_list int a = nL4stellate + nL23pyramidal; int b = a + nL5Apyramidal; int c = b + nL5Bpyramidal; int d_loc = c + nstarpyramidal; //nneuron //L4 if ((0 <= indexOfNeuron) && (indexOfNeuron < nL4stellate)) { typeOfNeuron = NeuronTypes.L4_STELLATE.getNum(); //logger.info("neuron type L4: " + typeOfNeuron); return typeOfNeuron; } //L2/3 if ((nL4stellate <= indexOfNeuron) && (indexOfNeuron < a)) { typeOfNeuron = NeuronTypes.L23_PYRAMIDAL.getNum(); //logger.info("neuron type L2/3: " + typeOfNeuron); return typeOfNeuron; } //L5A if ((a <= indexOfNeuron) && (indexOfNeuron < b)) { typeOfNeuron = NeuronTypes.L5A_PYRAMIDAL.getNum(); //logger.info("neuron type L5A: " + typeOfNeuron); return typeOfNeuron; } //L5B if ((b <= indexOfNeuron) && (indexOfNeuron < c)) { typeOfNeuron = NeuronTypes.L5B_PYRAMIDAL.getNum(); //logger.info("neuron type L5B: " + typeOfNeuron); return typeOfNeuron; } //star if ((c <= indexOfNeuron) && (indexOfNeuron < d_loc)) { typeOfNeuron = NeuronTypes.L4_STAR_PYRAMIDAL.getNum(); //logger.info("neuron type STAR: " + typeOfNeuron); return typeOfNeuron; } //logger.info("no neuron: " + typeOfNeuron); return typeOfNeuron; } @Override public WriteToHoc getHocData() { return new WriteToHocData(); } /** * * TODO: make a factory class.. to generate data */ public class WriteToHocData implements WriteToHoc { /** * Function to get the uEPSP value of a synapse connecting Neuron1 and Neuron2 depending on their types (simone) */ @Override public float get_uEPSP_Value(int typeN1, int typeN2) { float uEPSP = -1.0000f; //unitary EPSP variable for the various neuron type combinations //which type combination? -> which uEPSP? if ((typeN1 == NeuronTypes.L4_STELLATE.ordinal()) && (typeN2 == NeuronTypes.L4_STELLATE.ordinal())) { uEPSP = 0.0016f; //cout << "typeN1: L4, typeN2: L4, uEPSP: " << uEPSP << endl; } else if ((typeN1 == NeuronTypes.L4_STELLATE.ordinal()) && (typeN2 == NeuronTypes.L23_PYRAMIDAL.ordinal())) { uEPSP = 0.0007f; //cout << "typeN1: L4, typeN2: L2/3, uEPSP: " << uEPSP << endl; } else if ((typeN1 == NeuronTypes.L4_STELLATE.ordinal()) && (typeN2 == NeuronTypes.L5A_PYRAMIDAL.ordinal())) { uEPSP = 0.0006f; //cout << "typeN1: L4, typeN2: L5A, uEPSP: " << uEPSP << endl; } else if ((typeN1 == NeuronTypes.L23_PYRAMIDAL.ordinal()) && (typeN2 == NeuronTypes.L23_PYRAMIDAL.ordinal())) { uEPSP = 0.0010f; //cout << "typeN1: L2/3, typeN2: L2/3, uEPSP: " << uEPSP << endl; } else if ((typeN1 == NeuronTypes.L23_PYRAMIDAL.ordinal()) && (typeN2 == NeuronTypes.L5A_PYRAMIDAL.ordinal())) { uEPSP = 0.0008f; //cout << "typeN1: L2/3, typeN2: L5A, uEPSP: " << uEPSP << endl; } else if ((typeN1 == NeuronTypes.L23_PYRAMIDAL.ordinal()) && (typeN2 == NeuronTypes.L5B_PYRAMIDAL.ordinal())) { uEPSP = 0.0003f; //cout << "typeN1: L2/3, typeN2: L5B, uEPSP: " << uEPSP << endl; } else if ((typeN1 == NeuronTypes.L5A_PYRAMIDAL.ordinal()) && (typeN2 == NeuronTypes.L5A_PYRAMIDAL.ordinal())) { uEPSP = 0.0020f; //cout << "typeN1: L5A, typeN2: L5A, uEPSP: " << uEPSP << endl; } else if ((typeN1 == NeuronTypes.L5A_PYRAMIDAL.ordinal()) && (typeN2 == NeuronTypes.L23_PYRAMIDAL.ordinal())) { uEPSP = 0.0005f; //cout << "typeN1: L5A, typeN2: L2/3, uEPSP: " << uEPSP << endl; } else if ((typeN1 == NeuronTypes.L5B_PYRAMIDAL.ordinal()) && (typeN2 == NeuronTypes.L5B_PYRAMIDAL.ordinal())) { uEPSP = 0.0013f; //cout << "typeN1: L5B, typeN2: L5B, uEPSP: " << uEPSP << endl; } else { uEPSP = 0.0010f; //cout << "typeN1: " << typeN1 << ", typeN2: " << typeN2 << ", uEPSP: ??? " << uEPSP << endl; } return uEPSP; } @Override public final void writetohocChannels(Writer fw) throws IOException { int secProcCounter = 1; //counter for secundar procedures fw.append(" // na+ channels \n" + " forall insert na \n"); int ii = 0; for (; ii < getNumL4stellate(); ++ii) { if (ii % 101 == 100) { fw.append("} \n" + "proc init_cell" + secProcCounter++ + "(){ \n"); } fw.append(" forsec \"N" + ii + "dendrite\" gbar_na = gna_dend \n"); } for (; ii < getNumL4stellate() + getNumPyramidal(); ++ii) { if (ii % 101 == 100) { fw.append("} \n" + "proc init_cell" + secProcCounter++ + "(){ \n"); } fw.append(" forsec \"N" + ii + "dendrite\" gbar_na = gna_dend_pyr \n"); } for (; ii < nneuron; ++ii) { if (ii % 101 == 100) { fw.append("} \n" + "proc init_cell" + secProcCounter++ + "(){ \n"); } fw.append(" forsec \"N" + ii + "dendrite\" gbar_na = gna_dend \n"); } fw.append("} \n\n" + "proc init_cell" + secProcCounter++ + "() { \n"); ii = 0; for (; ii < getNumL4stellate(); ++ii) { if (ii % 26 == 25) { fw.append("} \n" + "proc init_cell" + secProcCounter++ + "(){ \n"); } fw.append(" forsec \"N" + ii + "axon\" { \n" + " insert kv \n" + " gbar_na = 0.06*gna_node \n" + " gbar_kv = gkv_axon \n" + " } \n"); } for (; ii < getNumL4stellate() + getNumPyramidal(); ++ii) { if (ii % 26 == 25) { fw.append("} \n" + "proc init_cell" + secProcCounter++ + "(){ \n"); } fw.append(" forsec \"N" + ii + "axon\" { \n" + " insert kv \n" + " gbar_na = 0.06*gna_node \n" + " gbar_kv = gkv_axon_pyr \n" + " } \n"); } for (; ii < nneuron; ++ii) { if (ii % 26 == 25) { fw.append("} \n" + "proc init_cell" + secProcCounter++ + "(){ \n"); } fw.append(" forsec \"N" + ii + "axon\" { \n" + " insert kv \n" + " gbar_na = 0.06*gna_node \n" + " gbar_kv = gkv_axon \n" + " } \n"); } fw.append("} \n\n" + " // kv delayed rectifier channels \n"); for (int i = 0; i < nneuron; i += 100) { fw.append("proc init_cell" + secProcCounter++ + "() { \n"); for (int j = i; j < i + 100 && j < nneuron; j++) { fw.append(" N" + j + "soma { insert kv gbar_kv = gkv_soma } \n"); } fw.append("} \n\n"); } fw.append("proc init_cell" + secProcCounter++ + "() { \n" + " // dendritic channels \n"); for (int i = 0; i < nneuron; ++i) { if (i % 21 == 20) { fw.append("} \n" + "proc init_cell" + secProcCounter++ + "(){ \n"); } fw.append(" forsec \"N" + i + "dendrite\" { \n" + " insert km gbar_km = gkm \n" + " insert kca gbar_kca = gkca \n" + " insert ca gbar_ca = gca \n" + " insert cad \n" + " } \n"); } fw.append("} \n\n" + "proc init_cell" + secProcCounter++ + "() { \n"); for (int i = 0; i < nneuron; ++i) { if (i % 11 == 10) { fw.append("} \n" + "proc init_cell" + secProcCounter++ + "(){ \n"); } fw.append(" N" + i + "soma { \n" + " insert km gbar_km = gkm \n" + " insert kca gbar_kca = gkca \n" + " insert ca gbar_ca = gca \n" + " insert cad \n" + " gbar_na = gna_soma \n" + " gbar_km = gkm_soma \n" + " gbar_kca = gkca_soma \n" + " gbar_ca = gca_soma \n" + " } \n"); } fw.append("\n" + " forall if(ismembrane(\"k_ion\")) ek = Ek \n" + " forall if(ismembrane(\"na_ion\")) { \n" + " ena = Ena \n" + " // seems to be necessary for 3d cells to shift Na kinetics -5 mV \n" + " vshift_na = -5 \n" + " } \n" + " forall if(ismembrane(\"ca_ion\")) { \n" + " eca = 140 \n" + " ion_style(\"ca_ion\",0,1,0,0,0) \n" + " vshift_ca = 0 \n" + " } \n" + "} \n\n"); for (int i = 0; i < secProcCounter; i++) { fw.append("init_cell" + i + "() \n"); } fw.append("\n"); fw.flush(); } @Override public final void writetohocAlphaSynapses(Writer fw) throws IOException { writetohocAlphaSynapses(fw, NeuronTypes.L4_STELLATE); writetohocAlphaSynapses(fw, NeuronTypes.L23_PYRAMIDAL); writetohocAlphaSynapses(fw, NeuronTypes.L5B_PYRAMIDAL); } /** * * Function to write alpha synapses to a hoc file. * * @param fw stream for the hoc file */ public final void writetohocAlphaSynapses(Writer fw, NeuronTypes neuronType) throws FileNotFoundException, IOException { String projectPath = NeuGenView.getInstance().getProjectDirPath(); String tcuDataPath = projectPath + NeuGenConstants.FILE_SEP + NeuGenConstants.TCU_DATA_FILE; FileReader tcuData = new FileReader(new File(tcuDataPath)); BufferedReader tcuDataBuffer = new BufferedReader(tcuData); String nextLine = null; List<String[]> dataList = new ArrayList<String[]>(); while ((nextLine = tcuDataBuffer.readLine()) != null) { nextLine = nextLine.trim(); String[] data = nextLine.split("\t"); dataList.add(data); } int ntime_sec = 100; int starttime = 140; int sumTime = ntime_sec + starttime; double[] tcutab = new double[ntime_sec]; double[] time = new double[ntime_sec]; int i = 0; for (int j = starttime; j < sumTime; ++j, i++) { String[] data = dataList.get(j); time[i] = Double.parseDouble(data[0]); tcutab[i] = Double.parseDouble(data[1]); } // Factor to rise weight of a synapse per micrometer. float wfactor = 0.001f; for (int j = 0; j < synapseList.size(); j++) { Cons synapse = synapseList.get(j); if (synapse.getNeuron1() != null) { continue; } if (neuronType.equals(NeuronTypes.L4_STELLATE)) { if (synapse.getNeuron2().getIndex() >= getNumL4stellate()) { continue; } } else if (neuronType.equals(NeuronTypes.L23_PYRAMIDAL)) { int nNum = getNumL4stellate() + getNumL23pyramidal(); if (synapse.getNeuron2().getIndex() < getNumL4stellate() || synapse.getNeuron2().getIndex() >= nNum) { continue; } } else if (neuronType.equals(NeuronTypes.L5B_PYRAMIDAL)) { int nNum = getNumL4stellate() + getNumL23pyramidal() + getNumL5Apyramidal(); int nNum2 = getNumL4stellate() + getNumPyramidal(); if (synapse.getNeuron2().getIndex() < nNum || synapse.getNeuron2().getIndex() > nNum2) { continue; } } else { continue; } for (int jj = 0; jj < 100; ++jj) { double prob = tcutab[jj]; if (getDrawNumber().fdraw() > prob) { continue; // no action for this synapse } int n_idx = synapse.getNeuron2().getIndex(); int c_idx = 0; for (Segment denSeg : synapse.getNeuron2DenSection().getSegments()) { if (denSeg.getId() == synapse.getNeuron2DenSectionSegment().getId()) { break; } c_idx++; } int sec_id = synapse.getNeuron2DenSection().getId(); float dd = NeuronalTreeStructure.getDendriteSectionData(synapse.getNeuron2DenSection(), c_idx); //float dd = neuronList.get(n_idx).getDendrites().get(d_idx).getdendritesectionData(sec_id, c_idx); fw.append("objectvar Synapse" + j + '_' + jj + "\n" + "N" + n_idx + "dendrite" + sec_id + " Synapse" + j + '_' + jj + " = new AlphaSynapse(" + dd + ")" + "\n" + "Synapse" + j + '_' + jj + ".onset = " + jj + "\n" + "Synapse" + j + '_' + jj + ".tau = 1.7" + "\n" + "Synapse" + j + '_' + jj + ".gmax = " + (1 + wfactor * synapse.getDendriticSomaDistance()) * 0.001 + "\n" // maximum value + "Synapse" + j + '_' + jj + ".e = 0" + "\n" + "\n"); fw.flush(); } } } @Override public final void writetohocExp2Synapses(Writer fw, Writer synFW) throws IOException { // Factor to rise weight of a synapse per micrometer. float wfactor = 0.001f; List<Cons> synapseList = getSynapseList(); for (int j = 0; j < synapseList.size(); j++) { Cons synapse = synapseList.get(j); int typeN1 = -1; int typeN2 = -1; if (synapse.getNeuron1() == null) { continue; } typeN1 = getTypeOfNeuron(synapse.getNeuron1().getIndex()); typeN2 = getTypeOfNeuron(synapse.getNeuron2().getIndex()); int n_idx = synapse.getNeuron2().getIndex(); int c_idx = 0; for (Segment denSeg : synapse.getNeuron2DenSection().getSegments()) { if (denSeg.getId() == synapse.getNeuron2DenSectionSegment().getId()) { break; } c_idx++; } int sec_id = synapse.getNeuron2DenSection().getId(); float dd = NeuronalTreeStructure.getDendriteSectionData(synapse.getNeuron2DenSection(), c_idx); //float dd = synapse.neuron2.getDendrites().get(d_idx).getdendritesectionData(sec_id, c_idx); //logger.info("dendrite secion data: " + dd); //int n1_idx = synapse.neuron1_idx; if (synFW != null) { //write functional synapse (NetCon) coordinates in file Point3f sc = synapse.getNeuron1AxSegment().getEnd(); synFW.append(sc.x + " " + sc.y + " " + sc.z + "\n"); synFW.flush(); } fw.append("\nobjectvar Synapse" + j + "\n" + "N" + n_idx + "dendrite" + sec_id + " Synapse" + j + " = new Exp2Syn(" + dd + ")" + "\n" + "Synapse" + j + ".tau1 = 0.2" + "\n" /* ms */ + "Synapse" + j + ".tau2 = 1.7" + "\n" /* ms */ + "Synapse" + j + ".e = 0.0" + "\n" /* reversal potential, mV */ + "objectvar Nc" + j + "\n"); Section ax_section = synapse.getNeuron1AxSection(); assert (ax_section.getLength() > 0.0); int axSegPos = 0; for (Segment axSeg : ax_section.getSegments()) { if (axSeg.getId() == synapse.getNeuron1AxSegment().getId()) { break; } axSegPos++; } float ax_local_position = (ax_section.getLength() * axSegPos) / ax_section.getLength(); assert (!Float.isInfinite(ax_local_position)); fw.append("N" + synapse.getNeuron1().getIndex() + ax_section.getName() + " Nc" + j + " = new NetCon(&v(" + ax_local_position + "), Synapse" + j + ", -10.0, 0.5, " + (1 + wfactor * synapse.getDendriticSomaDistance()) * get_uEPSP_Value(typeN1, typeN2) + ")" + "\n"); } if (synFW != null) { synFW.close(); } fw.flush(); } @Override public final void writetohocModel(Writer fw) throws IOException { fw.append("objref fih \n"); fw.append(" fih = new FInitializeHandler(2, \"mkmovie()\")\n"); fw.append("access N0soma\n"); fw.append("/*objref st\n"); fw.append("st=new IClamp(0.5)\n"); fw.append("st.dur = 10\n"); fw.append("st.del = 10\n"); fw.append("st.amp = 0.2*/\n\n"); fw.append("// --------------------------------------------------------------\n"); fw.append("// passive & active membrane\n"); fw.append("// --------------------------------------------------------------\n"); fw.append("ra = 150\n"); fw.append("global_ra = ra\n"); fw.append("rm = 30000\n"); fw.append("c_m = 0.75\n"); fw.append("//cm_myelin = 0.04 g_pas_node = 0.02\n"); fw.append("Ek = -90 \n"); fw.append("Ena = 60\n"); fw.append("gna_dend = 13\n"); fw.append("gna_dend_pyr = 19\n"); fw.append("gna_node = 30000\n"); fw.append("gna_soma = 0.05*gna_node\n\n"); fw.append("gkv_axon = 2000\n"); fw.append("gkv_axon_pyr = 3000\n"); fw.append("gkv_soma = 2000\n"); fw.append("gca = .3\n"); fw.append("gkm = .1\n"); fw.append("gkca = 3\n"); fw.append("gca_soma = gca\n"); fw.append("gkm_soma = gkm\n"); fw.append("gkca_soma = gkca\n\n"); fw.append("proc init_cell0() {\n"); fw.append(" // passive\n"); fw.append(" forall {\n"); fw.append(" insert pas\n"); fw.append(" Ra = ra\n"); fw.append(" cm = c_m\n"); fw.append(" g_pas = 1/rm\n"); fw.append(" e_pas = v_init\n"); fw.append(" }\n\n"); fw.flush(); } } }