/** * "FNS" (Firnet NeuroScience), ver.3.x * * FNS is an event-driven Spiking Neural Network framework, oriented * to data-driven neural simulations. * * (c) 2020, Gianluca Susi, Emanuele Paracone, Mario Salerno, * Alessandro Cristini, Fernando Maestú. * * CITATION: * When using FNS for scientific publications, cite us as follows: * * Gianluca Susi, Pilar Garcés, Alessandro Cristini, Emanuele Paracone, * Mario Salerno, Fernando Maestú, Ernesto Pereda (2020). * "FNS: an event-driven spiking neural network simulator based on the * LIFL neuron model". * Laboratory of Cognitive and Computational Neuroscience, UPM-UCM * Centre for Biomedical Technology, Technical University of Madrid; * University of Rome "Tor Vergata". * Paper under review. * * FNS is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * FNS 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with FNS. If not, see <http://www.gnu.org/licenses/>. * * ----------------------------------------------------------- * * Website: http://www.fnsneuralsimulator.org * * Contacts: fnsneuralsimulator (at) gmail.com * gianluca.susi82 (at) gmail.com * emanuele.paracone (at) gmail.com * * * ----------------------------------------------------------- * ----------------------------------------------------------- **/ package utils.statistics; import java.io.BufferedWriter; import java.io.File; import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ArrayBlockingQueue; import connectivity.conn_package.PackageReader; public class StatisticsCollector /*extends Thread*/ { private final String TAG = "[Statistic Collector] "; private volatile Long active=0l; private volatile Long passive=0l; private volatile Long passive2active=0l; private volatile Long active2passive=0l; public volatile Long missedFires=0l; private BlockingQueue<CollectedBurn> burningSpikesQueue; private BlockingQueue<CollectedFire> firingSpikesQueue; private volatile ArrayList<Double> firstFiringTimes= null; private volatile Double minMissedAxonalDelay = Double.MAX_VALUE; private volatile Double minNe_xn_ratio; private volatile Double maxNe_xn_ratio; private volatile Boolean badCurve=false; private volatile long firingSpikesCounter=0l; private volatile long burningSpikesCounter=0l; private int serializeAfter = 10000; private volatile int wrotes_split=0; private volatile String filename = ""; private volatile Boolean matlab=false; private volatile Boolean gephi=false; private volatile Boolean reducedOutput=false; private Boolean superReducedOutput=false; private int count=1; private volatile ArrayList<CollectedFire> newFires= new ArrayList<CollectedFire>(); private volatile ArrayList<CollectedBurn> newBurns= new ArrayList<CollectedBurn>(); private Lock lock = new ReentrantLock(); private Condition eventQueueCondition = lock.newCondition(); private Boolean keepRunning=true; private String defFileName=null; private BurningWriter burningWriter; private FiringWriter firingWriter; public void start(){ burningWriter.start(); firingWriter.start(); } public void kill(){ keepRunning=false; burningWriter.close(); firingWriter.close(); } public void setSerializeAfter(int sa){ serializeAfter = sa; burningSpikesQueue= new ArrayBlockingQueue<CollectedBurn>(sa); firingSpikesQueue= new ArrayBlockingQueue<CollectedFire>(sa); burningWriter= new BurningWriter( filename, burningSpikesQueue); firingWriter= new FiringWriter( filename, firingSpikesQueue); } public int getSerializeAfter(){ return serializeAfter; } public void setFilename(String filename){ this.filename=filename; } public void setMatlab() { matlab=true; } public void setReducedOutput() { reducedOutput=true; } public void setSuperReducedOutput() { superReducedOutput=true; } public void setGephi() { gephi=true; } public synchronized void collectActive(){ ++active; } public synchronized void collectPassive2active(){ ++passive2active; } public synchronized void collectActive2passive(){ ++active2passive; } public synchronized void collectPassive(){ ++passive; } <<<<<<< HEAD //public synchronized void collectFireSpike(CollectedFire cf){ // try{ // firingSpikesQueue.put(cf); // } // catch (InterruptedException e) { // e.printStackTrace(); // } //} public synchronized void collectFireSpike( Integer firingNodeId, Long firingNeuronId, Double firingTime, Long maxN, Double compressionFactor, Boolean isExcitatory, Boolean isExternal){ try{ firingSpikesQueue.put( new CollectedFire( firingNodeId, firingNeuronId, firingTime, maxN, compressionFactor, isExcitatory, isExternal )); ======= public synchronized void collectFireSpike(CollectedFire cf){ try{ firingSpikesQueue.put(cf); >>>>>>> 48bb69b3e778691a096596083425b528609c0729 } catch (InterruptedException e) { e.printStackTrace(); } } //public synchronized void collectFireSpike( // Integer firingNodeId, // Long firingNeuronId, // Double firingTime, // Long maxN, // Double compressionFactor, // Boolean isExcitatory, // Boolean isExternal){ // //processFireSpike( // try{ // firingSpikesQueue.put( // new CollectedFire( // firingNodeId, // firingNeuronId, // firingTime, // maxN, // compressionFactor, // isExcitatory, // isExternal // )); // } // catch (InterruptedException e) { // e.printStackTrace(); // } // //new_event(); //} //private void processFireSpike(CollectedFire cf) { // FiringNeuron fn= new FiringNeuron( // cf.getFiringNodeId(), // cf.getFiringNeuronId(), // cf.getFiringTime(), // cf.getIsExcitatory(), // cf.getIsExternal()); // firingSpikesHashMap.put(new Long(firingSpikesCounter), fn); // //} // ++firingSpikesCounter; // if ((firingSpikesCounter%serializeAfter)==0){ // makeCsv(filename); // //if (firstFiringNeurons==null) // // simulatedTime=cf.getFiringTime(); // } //} <<<<<<< HEAD //public synchronized void collectBurnSpike(CollectedBurn cb) { // try{ // burningSpikesQueue.put(cb); // } // catch (InterruptedException e) { // e.printStackTrace(); // } // //new_event(); //} public synchronized void collectBurnSpike( Long firingNeuronId, Integer firingNodeId, Long burningNeuronId, Integer burningNodeId, Double burnTime, Boolean fromExternalSource, Double fromState, Double stepInState, Double postsynapticWeight, Double presynapticWeight, Double timeToFire, Double fireTime) { try{ burningSpikesQueue.put( new CollectedBurn( firingNeuronId, firingNodeId, burningNeuronId, burningNodeId, burnTime, fromExternalSource, fromState, stepInState, postsynapticWeight, presynapticWeight, timeToFire, fireTime) ); } catch (InterruptedException e) { e.printStackTrace(); } } ======= public synchronized void collectBurnSpike(CollectedBurn cb) { try{ burningSpikesQueue.put(cb); } catch (InterruptedException e) { e.printStackTrace(); } //new_event(); } //public synchronized void collectBurnSpike( // Long firingNeuronId, // Integer firingNodeId, // Long burningNeuronId, // Integer burningNodeId, // Double burnTime, // Boolean fromExternalSource, // Double fromState, // Double stepInState, // Double postsynapticWeight, // Double presynapticWeight, // Double timeToFire, // Double fireTime) { // try{ // burningSpikesQueue.put( // new CollectedBurn( // firingNeuronId, // firingNodeId, // burningNeuronId, // burningNodeId, // burnTime, // fromExternalSource, // fromState, // stepInState, // postsynapticWeight, // presynapticWeight, // timeToFire, // fireTime) // ); // } // //catch (InterruptedException e) { // // e.printStackTrace(); // //} // //new_event(); //} //private void processBurnSpike(CollectedBurn cb) { // //if (checkall ||( NOI.get(cb.getBurningNodeId())!=null )){ // burningSpikesHashMap.put(new Long(burningSpikesCounter), cb); // burningSpikesQueue.put(cb);. // //} // ++burningSpikesCounter; //} >>>>>>> 48bb69b3e778691a096596083425b528609c0729 //private void processBurnSpike(CollectedBurn cb) { // //if (checkall ||( NOI.get(cb.getBurningNodeId())!=null )){ // burningSpikesHashMap.put(new Long(burningSpikesCounter), cb); // burningSpikesQueue.put(cb);. // //} // ++burningSpikesCounter; //} public synchronized void collectMissedFire(Double missedAxonalDelay){ if (missedAxonalDelay<minMissedAxonalDelay) minMissedAxonalDelay=missedAxonalDelay; ++missedFires; } //public void printFirePlot(){ // double [] x = new double [firingTimes.size()]; // double [] y = new double [firingNeurons.size()]; // for (int i=0; i<firingNeurons.size();++i){ // x[i]=firingTimes.get(i); // y[i]=firingNeurons.get(i).doubleValue(); // } // System.out.println( // "[Statistics Collector] X size:" // +x.length // +", Y size:" // +y.length); // System.out.println( // "[Statistics Collector] firing times size:" // +firingTimes.size() // +", firing neurons size:" // +firingNeurons.size()); // ScatterPlotter frame = // new ScatterPlotter("FNS", x, y,simulatedTime); // frame.setVisible(); //} //public void printFirePlot(String outputFileName){ // double [] x = new double [firstFiringTimes.size()]; // double [] y = new double [firstFiringNeurons.size()]; // for (int i=0; i<firstFiringNeurons.size();++i){ // x[i]=firstFiringTimes.get(i); // y[i]=firstFiringNeurons.get(i).doubleValue(); // } // System.out.println( // "[Statistics Collector] X size:" // +x.length // +", Y size:" // +y.length); // System.out.println( // "[Statistics Collector] firing times size:" // +firstFiringTimes.size() // +", firing neurons size:" // +firstFiringNeurons.size()); // ScatterPlotter frame = // new ScatterPlotter( // "F. N. S.", // x, // y, // simulatedTime,outputFileName); // frame.setVisible(); //} //public void makeCsv(String filename){ // if (filename=="") // return; // ++wrotes_split; // PrintWriter burnWriter; // PrintWriter fireWriter; // Boolean new_burn_file=false; // Boolean new_fire_file=false; // File towritefile; // FileWriter fire_fw; // CollectedBurn cb; // CollectedFire cf; // DecimalFormat df = superReducedOutput? // new DecimalFormat("#.###"): // new DecimalFormat("#.################"); // try { // //Iterator<Long> it = burningSpikesHashMap.keySet().iterator(); // if (firstFiringNeurons==null) { //// int count = 1; // for(;;++count) { // if (reducedOutput) // towritefile= new File( // filename // +String.format("%03d", count) // +"_burning_r.csv"); // if (superReducedOutput) // towritefile= new File( // filename // +String.format("%03d", count) // +"_burning_R.csv"); // else // towritefile= new File( // filename // +String.format("%03d", count) // +"_burning.csv"); // if(!towritefile.exists()){ // defFileName=filename+String.format("%03d", count); // break; // } // } // } // if (reducedOutput) // towritefile= new File(defFileName+"_burning_r.csv"); // else if (superReducedOutput) // towritefile= new File(defFileName+"_burning_R.csv"); // else // towritefile= new File(defFileName+"_burning.csv"); // if (!towritefile.exists()){ // towritefile.createNewFile(); // new_burn_file=true; // } // FileWriter fw = new FileWriter(towritefile,true); // BufferedWriter bw = new BufferedWriter(fw); // burnWriter = new PrintWriter(bw); // if (new_burn_file){ // if (!(reducedOutput||superReducedOutput)) // burnWriter.println( // "Burning Time, " // + "Firing Node, " // + "Firing Neuron, " // + "Burning Node, " // + "Burning Neuron, " // + "External Source, " // + "From Internal State, " // + "To Internal State, " // + "Step in State, " // +" Post Synaptic Weight, " // + "Pre Synaptic Weight, " // + "Instant to Fire, " // + "(Afferent) Firing Time"); // } // //while (it.hasNext()){ // while (cb=burningSpikesQueue.take()){ // //Long key = it.next(); // //Double fromState = cb.getFromState(); // //Double stepInState=cb.getStepInState(); // Double fromState = cb.getFromState(); // Double stepInState=cb.getStepInState(); // String stepInStateToPrint; // String fromStateToPrint; // String toStateToPrint; // if (fromState==null){ // fromStateToPrint=(reducedOutput||superReducedOutput)?"0":"refr"; // toStateToPrint=(reducedOutput||superReducedOutput)?"0":"refr"; // } // else{ // fromStateToPrint=""+df.format(fromState); // toStateToPrint=""+df.format(fromState+stepInState); // } // if (stepInState==null) // stepInStateToPrint=(reducedOutput||superReducedOutput)?"0":"refr"; // else // stepInStateToPrint=""+df.format(stepInState); // if (reducedOutput||superReducedOutput) // burnWriter.println( // df.format(cb.getBurnTime())+", " // + cb.getBurningNodeId()+", " // + cb.getBurningNeuronId()+", " // + toStateToPrint // ); // else // burnWriter.println( // df.format(cb.getBurnTime())+", " // + cb.getFiringNodeId()+", " // + cb.getFiringNeuronId()+", " // + cb.getBurningNodeId()+", " // + cb.getBurningNeuronId()+", " // + cb.fromExternalInput()+", " // + fromStateToPrint +", " // + toStateToPrint +", " // + stepInStateToPrint+", " // + df.format(cb.getPostSynapticWeight())+", " // + df.format(cb.getPreSynapticWeight())+"," // + df.format(cb.getTimeToFire())+"," // + df.format((cb.getFireTime()!=null)? // cb.getFireTime():0) // ); //// System.out.println("[statistics]" + df.format(cb.getPostSynapticWeight())); // } // burnWriter.flush(); // burnWriter.close(); // System.out.println( // "[Statistics Collector] " // +towritefile.getAbsolutePath() // +" update " // +wrotes_split // +" complete."); // //it=firingSpikesHashMap.keySet().iterator(); // if (reducedOutput) // towritefile= new File(defFileName+"_firing_r.csv"); // else if (superReducedOutput) // towritefile= new File(defFileName+"_firing_R.csv"); // else // towritefile= new File(defFileName+"_firing.csv"); // if (towritefile.exists()) // fire_fw = new FileWriter(towritefile,true); // else{ // towritefile.createNewFile(); // fire_fw = new FileWriter(towritefile); // new_fire_file=true; // } // BufferedWriter fire_bw = new BufferedWriter(fire_fw); // fireWriter=new PrintWriter(fire_bw); // if (new_fire_file){ // if (!(reducedOutput||superReducedOutput)) // fireWriter.println( // "Firing Time," // +" Firing Node," // +" Firing Neuron, " // +" Neuron Type," // +" External Source"); // } // while (cf=collectedFireSpikesQueue.take()){ // //Long key = it.next(); // String excitStr; // String isExternalStr; // if (cf.isExcitatory()) // excitStr="excitatory"; // else // excitStr="inhibitory"; // if (cf.isExternal()) // isExternalStr=(reducedOutput||superReducedOutput)?"1":"true"; // else // isExternalStr=(reducedOutput||superReducedOutput)?"0":"false"; // if (reducedOutput||superReducedOutput) // fireWriter.println( // df.format(cf.getFiringTime())+", " // +cf.getFiringNodeId()+", " // + cf.getFiringNeuronId()+", " // + isExternalStr // ); // else // fireWriter.println( // df.format(cf.getFiringTime())+", " // +cf.getFiringNodeId()+", " // + cf.getFiringNeuronId()+", " // + excitStr+", " // + cf.isExternal() // ); // } // fireWriter.flush(); // fireWriter.close(); // if (matlab) // makeMatlabCsv(); // if (gephi) // makeGephiCsv(); // reset(); // System.out.println( // "[Statistics Collector] " // +towritefile.getAbsolutePath() // +" update " // +wrotes_split // +" complete."); // } catch (FileNotFoundException | UnsupportedEncodingException e) { // e.printStackTrace(); // } catch (IOException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } // System.out.println("[Statistics Collector] Firings:"+firingSpikesCounter); //} //private void makeMatlabCsv(){ // if (filename=="") // return; // PrintWriter burnWriter; // PrintWriter fireWriter; // try { // //Iterator<Long> it = burningSpikesHashMap.keySet().iterator(); // File towritefile; // FileWriter fire_fw; // towritefile= new File(defFileName+"_burning_matlab.csv"); // if (!towritefile.exists()) // towritefile.createNewFile(); // FileWriter fw = new FileWriter(towritefile,true); // BufferedWriter bw = new BufferedWriter(fw); // burnWriter = new PrintWriter(bw); // while (it.hasNext()){ // Long key = it.next(); // Double fromState = cb.getFromState(); // Double stepInState=cb.getStepInState(); // String stepInStateToPrint; // String fromStateToPrint; // String toStateToPrint; // //String fromExternalInput; // String refrString="0"; // if (fromState==null){ // fromStateToPrint=refrString; // toStateToPrint=refrString; // } // else{ // fromStateToPrint=fromState.toString(); // toStateToPrint=""+(fromState+stepInState); // } // if (stepInState==null) // stepInStateToPrint="0"; // else // stepInStateToPrint=stepInState.toString(); // burnWriter.println( // cb.getBurnTime().toString()+", " // + cb.getFiringNodeId()+", " // + cb.getFiringNeuronId()+", " // + cb.getBurningNodeId()+", " // + cb.getBurningNeuronId()+", " // + cb.fromExternalInputInteger()+", " // + fromStateToPrint +", " // + toStateToPrint +", " // + stepInStateToPrint+", " // + cb.getPostSynapticWeight()+", " // + cb.getPreSynapticWeight()+"," // + cb.getTimeToFire()+"," // + cb.getFireTime() // ); // } // burnWriter.flush(); // burnWriter.close(); // System.out.println( // "[Statistics Collector] " // +towritefile.getAbsolutePath() // +" update " // +wrotes_split // +" complete."); // it=firingSpikesHashMap.keySet().iterator(); // towritefile= new File(defFileName+"_firing_matlab.csv"); // if (towritefile.exists()) // fire_fw = new FileWriter(towritefile,true); // else{ // towritefile.createNewFile(); // fire_fw = new FileWriter(towritefile); // } // BufferedWriter fire_bw = new BufferedWriter(fire_fw); // fireWriter=new PrintWriter(fire_bw); // while (it.hasNext()){ // Long key = it.next(); // fireWriter.println( // cf.getFiringTime().toString()+", " // +cf.getFiringNodeId()+", " // + cf.getFiringNeuronId()+", " // + (cf.isExcitatory()?'1':'0')+", " // + (cf.isExternal()?'1':'0') // ); // } // fireWriter.flush(); // fireWriter.close(); // System.out.println("[Statistics Collector] "+towritefile.getAbsolutePath()+" update "+wrotes_split+" complete."); // } catch (FileNotFoundException | UnsupportedEncodingException e) { // e.printStackTrace(); // } catch (IOException e) { // e.printStackTrace(); // } //} //private void makeGephiCsv(){ // if (filename=="") // return; // PrintWriter burnWriter; // PrintWriter fireWriter; // try { // //Iterator<Long> it = burningSpikesHashMap.keySet().iterator(); // File towritefile; // FileWriter fire_fw; // towritefile= new File(defFileName+"_gephi.csv"); // if (!towritefile.exists()) // towritefile.createNewFile(); // FileWriter fw = new FileWriter(towritefile,true); // BufferedWriter bw = new BufferedWriter(fw); // burnWriter = new PrintWriter(bw); // burnWriter.println( "Firing, Burning"); // while (it.hasNext()){ // Long key = it.next(); // if(!cb.fromExternalInput()){ // burnWriter.println( // + cb.getFiringNodeId()+"-" // + cb.getFiringNeuronId()+", " // + cb.getBurningNodeId()+"-" // + cb.getBurningNeuronId()); // } // } // burnWriter.flush(); // burnWriter.close(); // System.out.println( // "[Statistics Collector] " // +towritefile.getAbsolutePath() // +" update " // +wrotes_split // +" complete."); // } catch (FileNotFoundException | UnsupportedEncodingException e) { // e.printStackTrace(); // } catch (IOException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } //} public void setMinMaxNe_xn_ratios( Double minNe_xn_ratio, Double maxNe_xn_ratio){ this.minNe_xn_ratio=minNe_xn_ratio; this.maxNe_xn_ratio=maxNe_xn_ratio; } public void PrintResults(){ String minNe_xn_ratioStr = (minNe_xn_ratio==PackageReader.MIN_NE_EN_RATIO_DEF)? "no connection between nodes":(""+minNe_xn_ratio); String maxNe_xn_ratioStr = (maxNe_xn_ratio==PackageReader.MAX_NE_EN_RATIO_DEF)? "no connection between nodes":(""+maxNe_xn_ratio); //System.out.println("active to active:"+active); //System.out.println("active to passive:"+active2passive); //System.out.println("passive to passive:"+passive); //System.out.println("passive to active:"+passive2active); // System.out.println("min Ne en ratio:"+minNe_xn_ratioStr); // System.out.println("max Ne en ratio:"+maxNe_xn_ratioStr); System.out.println("missed Fires:"+missedFires); if (missedFires>0) System.out.println("minimum missed fire axonal delay:"+minMissedAxonalDelay); System.out.println("Good curve:"+(!badCurve)); } public void setBadCurve(){ badCurve=true; } //public void setNodes2checkMask(BigInteger mask){ // region2checkMask=mask; //} //public void setNOI(HashMap <Integer, Boolean> NOI){ // this.NOI=NOI; //} //public void checkAll(){ // checkall=true; //} }