/**
* "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;
//}
}