package cnslab.cnsnetwork;
import java.io.*;
import java.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jpvm.jpvmException;
import jpvm.jpvmTaskId;
import cnslab.cnsmath.*;
import edu.jhu.mb.ernst.engine.DiscreteEvent;
import edu.jhu.mb.ernst.engine.DiscreteEventQueue;
import edu.jhu.mb.ernst.model.ModelFactory;
import edu.jhu.mb.ernst.model.ModulatedSynapse;
import edu.jhu.mb.ernst.model.Synapse;
import edu.jhu.mb.ernst.util.seq.Seq;
import edu.jhu.mb.ernst.util.slot.ErnstQueueSlot;
import edu.jhu.mb.ernst.util.slot.Slot;
/***********************************************************************
* Network structure to organize all the small pieces (neurons, layers,
* axons, recorders, etc.) together.
*
* @version
* $Date: 2012-08-04 20:43:22 +0200 (Sat, 04 Aug 2012) $
* $Rev: 104 $
* $Author: croft $
* @author
* Yi Dong
* @author
* David Wallace Croft
***********************************************************************/
public class Network
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
{
private static final Class<Network>
CLASS = Network.class;
private static final Logger
LOGGER = LoggerFactory.getLogger ( CLASS );
//
public int
countTrial,
expIdBack,
trialIdBack;
public Experiment experiment;
/** Keep track of current simulated subExp id */
public int subExpId;
/** Keep track of current Trials. */
public int trialId;
/** Size of Xedge */
public int xEdge;
/** Size of Yedge */
public int yEdge;
/** a data structure map "pre,x,y,suf" to neuron index */
public Map<String, Integer> cellmap;
/** the seed value for this network */
public Seed seed;
/** the system background firing rates */
public SimulatorParser simulatorParser;
/** the minimum synaptic delay */
public double minSynapticDelay;
/** for the output of the slave hosts */
public PrintStream p;
/** the parallel machine informations */
public JpvmInfo info;
/** used by the root host to monitor other host's time */
public double [ ] localTime;
/** spike buffer to store the neuron spikes which needs to be sented */
public SpikeBuffer [ ] spikeBuffers;
/** used for keep record of received spikes */
public int [ ] received;
/** recorded intracellular info */
public IntraRecBuffer intraRecBuffers;
/** recorded info buffer */
public RecordBuffer recordBuff;
/** neuron index base, the real index is index+base */
public int base;
/** the root broadcasting time */
public double rootTime;
/** the end of Trial time */
public double endOfTrial;
/** An array of neurons used in current Nethosts */
public Neuron [ ] neurons;
/** A data structure mapping neuron id to the neuron's Axon. */
public Map<Integer, Axon> axons;
/** Store the recorded data. */
public RecorderData recorderData;
/** flag for the computation and communication threads to stop */
public boolean stop;
/** Flag to indicate whether the trial is done or not */
public boolean trialDone;
/** trial start flag */
public boolean startSig;
/** flag for trial end */
public boolean spikeState = true;
// protected final instance variables
protected final ModelFactory modelFactory;
protected final DiscreteEventQueue discreteEventQueue;
// protected non-final instance variables
/** The neuron fire queue */
protected Queue<FireEvent> fireQueue;
/** The (internal) input spike queue */
protected Queue<InputEvent> inputQueue;
/** The (external) input queue */
// used for poisson background firing event queue
protected Queue<PInputEvent> poissonQueue;
// private instance variables
private final Seq<ModulatedSynapse> modulatedSynapseSeq;
//
private Slot<FireEvent> fireEventSlot;
private Slot<InputEvent> inputEventSlot;
private Slot<PInputEvent> pInputEventSlot;
////////////////////////////////////////////////////////////////////////
// constructor methods
////////////////////////////////////////////////////////////////////////
public Network (
final ModelFactory modelFactory,
final DiscreteEventQueue discreteEventQueue,
final Seq<ModulatedSynapse> modulatedSynapseSeq,
final Neuron [ ] neurons,
final Map<Integer, Axon> axons,
final double minSynapticDelay,
final SimulatorParser simulatorParser,
final Seed seed )
////////////////////////////////////////////////////////////////////////
{
this.modelFactory = modelFactory;
this.discreteEventQueue = discreteEventQueue;
this.modulatedSynapseSeq = modulatedSynapseSeq;
this.neurons = neurons;
this.axons = axons;
this.minSynapticDelay = minSynapticDelay;
this.simulatorParser = simulatorParser;
this.seed = seed;
this.recorderData = new RecorderData ( );
}
public Network (
final ModelFactory modelFactory,
final DiscreteEventQueue discreteEventQueue,
final Seq<ModulatedSynapse> modulatedSynapseSeq,
final Neuron [ ] neurons,
final Map<Integer, Axon> axons,
final JpvmInfo info,
final int base,
final double minSynapticDelay,
final SimulatorParser simulatorParser,
final Seed seed,
final Experiment experiment )
////////////////////////////////////////////////////////////////////////
{
this.modelFactory = modelFactory;
this.discreteEventQueue = discreteEventQueue;
this.modulatedSynapseSeq = modulatedSynapseSeq;
this.neurons = neurons;
this.axons = axons;
this.info = info;
this.base = base;
this.minSynapticDelay = minSynapticDelay;
this.simulatorParser = simulatorParser;
this.seed = seed;
this.experiment = experiment;
this.recorderData = new RecorderData ( );
}
public Network (
final ModelFactory modelFactory,
final DiscreteEventQueue discreteEventQueue,
final Seq<ModulatedSynapse> modulatedSynapseSeq,
final Experiment experiment,
final JpvmInfo info,
final int base,
final double minSynapticDelay,
final SimulatorParser simulatorParser,
final Seed seed )
////////////////////////////////////////////////////////////////////////
{
this.modelFactory = modelFactory;
this.discreteEventQueue = discreteEventQueue;
this.modulatedSynapseSeq = modulatedSynapseSeq;
this.experiment = experiment;
this.info = info;
this.base = base;
this.minSynapticDelay = minSynapticDelay;
this.simulatorParser = simulatorParser;
this.seed = seed;
this.recorderData = new RecorderData ( );
}
////////////////////////////////////////////////////////////////////////
// accessor methods
////////////////////////////////////////////////////////////////////////
public DiscreteEventQueue getDiscreteEventQueue ( )
////////////////////////////////////////////////////////////////////////
{
return discreteEventQueue;
}
public synchronized double getLocalTime ( final int i )
////////////////////////////////////////////////////////////////////////
{
return localTime [ i ];
}
public Slot<FireEvent> getFireEventSlot ( )
////////////////////////////////////////////////////////////////////////
{
return fireEventSlot;
}
public FireEvent getFirstFireEvent ( )
////////////////////////////////////////////////////////////////////////
{
return fireQueue.firstItem ( );
}
public InputEvent getFirstInputEvent ( )
////////////////////////////////////////////////////////////////////////
{
return inputQueue.firstItem ( );
}
public PInputEvent getFirstPInputEvent ( )
////////////////////////////////////////////////////////////////////////
{
return poissonQueue.firstItem ( );
}
public Slot<InputEvent> getInputEventSlot ( )
////////////////////////////////////////////////////////////////////////
{
return inputEventSlot;
}
public Slot<PInputEvent> getPInputEventSlot ( )
////////////////////////////////////////////////////////////////////////
{
return pInputEventSlot;
}
////////////////////////////////////////////////////////////////////////
// mutator methods
////////////////////////////////////////////////////////////////////////
public void clearQueues ( )
////////////////////////////////////////////////////////////////////////
{
fireQueue .clear ( );
inputQueue .clear ( );
poissonQueue.clear ( );
discreteEventQueue.clear ( );
}
/***********************************************************************
* set a new value to localTime
*
* @param localTime
* the new value to be used
***********************************************************************/
public synchronized void setLocalTime (
final double localTime,
final int i )
////////////////////////////////////////////////////////////////////////
{
this.localTime [ i ] = localTime;
}
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/***********************************************************************
* stop the testRun();
***********************************************************************/
public void stopRun ( )
////////////////////////////////////////////////////////////////////////
{
stop = true;
}
/***********************************************************************
* Initializes the Network.
* fill up the first item for inputQueue, fireQueue, poissonQueue
* (the implementation of the queue is changed here),
* Initialized SyncNeuron (Index is the number of neurons).
***********************************************************************/
public void initNet ( )
////////////////////////////////////////////////////////////////////////
{
// subExpId=0; //the first subExp
// trialId=-1; // the first trial;
// double tmp_time;
// minDelay = 0.001; //minimum delay is 1ms
// inputQueue = new PriQueue<InputEvent>(); // assign the queue
// inputQueue = new FiboQueue<InputEvent>(); // assign the queue
// inputQueue = new TreeQueue<InputEvent>(); // assign the queue
// assign the queue
inputQueue = new MTreeQueue<InputEvent> ( );
inputEventSlot = new ErnstQueueSlot<InputEvent> ( inputQueue );
// fireQueue = new TreeQueue<FireEvent>();
fireQueue = new MTreeQueue<FireEvent> ( );
fireEventSlot = new ErnstQueueSlot<FireEvent> ( fireQueue );
// if(bFreq>0.0)
// {
// assign the queue
poissonQueue = new MTreeQueue<PInputEvent> ( );
pInputEventSlot = new ErnstQueueSlot<PInputEvent> ( poissonQueue );
// }
stop = false;
if ( info != null )
{
spikeBuffers = new SpikeBuffer [ info.numTasks ];
// adding the clock neuron at the end of neuron list
neurons [ neurons.length - 1 ] = new SYNNeuron ( this );
for ( int i = 0; i < info.numTasks; i++ )
{
spikeBuffers [ i ] = new SpikeBuffer ( );
}
recordBuff = new RecordBuffer ( );
received = new int [ info.numTasks ];
for ( int iter = 0; iter < info.numTasks; iter++ )
{
// leave mark here
received [ iter ] = 1;
}
intraRecBuffers
= new IntraRecBuffer ( experiment.recorder.intraNeurons ( ) );
// send initial input spikes from the sensory neuron to all the
// neurons in the network
/*
for(int i= 1; i< neurons.length; i++)
{
// 5Hz background input
tmp_time=-Math.log(Cnsran.ran2(idum))/5.0;
// sensory neuron send spikes to the other neurons
inputQueue.insertItem( new InputEvent(0,tmp_time,i,1e-10));
}
inputQueue.show();
*/
/*
if(bFreq>0.0)
{
// poissonQueue = new PriQueue<PInputEvent>(); // assign the queue
poissonQueue = new MTreeQueue<PInputEvent>(); // assign the queue
// poissonQueue = new TreeQueue<PInputEvent>(); // assign the queue
for(int i=0; i<neurons.length; i++)
{
if(!neurons[i].isSensory())
{
poissonQueue.insertItem (
new PInputEvent (
-Math.log ( Cnsran.ran2 ( idum ) ) / bFreq,
new Synapse ( base+i, 1e-10, 0 ),
0 ) );
}
}
}
*/
/*
for(int i=0; i<neurons.length; i++)
{
if(neurons[i].isSensory())
{
// sensory neuron send spikes to the other neurons
fireQueue.insertItem( new FireEvent(i+base,0.0));
}
}
*/
try
{
final jpvmTaskId parentJpvmTaskId = info.parentJpvmTaskId;
final String
host = parentJpvmTaskId == null
? "null-task-id" : parentJpvmTaskId.getHost ( );
final FileOutputStream out = new FileOutputStream (
"log/"
+ host
+ "_myfile"
+ info.idIndex
+ ".txt" );
p = new PrintStream ( out );
// p.println(base+neurons[neurons.length-1].toString());
p.println ( "Logfile start" );
}
catch ( final Exception e )
{
e.printStackTrace ( );
LOGGER.error ( e.getMessage ( ), e );
}
final String curDir = System.getProperty ( "user.dir" );
p.println ( curDir );
//added
/*
for(int iter=0;iter<info.numTasks;iter++)
{
while(!received[iter].empty())
{
received[iter].pop();
}
received[iter].push(new Object());
}
*/
//added over
}
// init();
}
/***********************************************************************
* Initialize the queues, put the first element into each of the queues.
*
* Called from PRun.run().
***********************************************************************/
public void init ( )
////////////////////////////////////////////////////////////////////////
{
// I added this as I was worried that the queues were not being
// cleared between repetitions of subexperiments.
// But then again, maybe there are special elements that need to
// stay in there for distributed computing. I need to look into the
// differences between init() and initNet() and when they are called.
// clearQueues ( );
discreteEventQueue.clear ( );
final SubExp subExp = experiment.subExp [ subExpId ];
final Collection<DiscreteEvent>
discreteEventCollection = subExp.getDiscreteEventCollection ( );
if ( discreteEventCollection != null )
{
discreteEventQueue.addAll ( discreteEventCollection );
}
clearModulationFactors ( );
// double tmp_time;
// minimum delay is 1ms
// minDelay = 0.001;
stop = false;
// trialDone=false;
spikeState = true;
/* this modification make old simulator done's run any more
trialId++;
if(trialId == exp.subExp[subExpId].repetition)
{
trialId =0;
subExpId++;
}
*/
// p.println("sub "+subExpId+ "tri: "+trialId);
// only initialize when subExp is within the range
if ( subExpId < experiment.subExp.length )
{
/*
for(int iter=0;iter<info.numTasks;iter++)
{
while(!received[iter].empty())
{
received[iter].pop();
}
received[iter].push(new Object());
}
*/
if ( info != null )
{
for ( int i = 0; i < info.numTasks; i++ )
{
spikeBuffers [ i ].buff.clear ( );
}
}
// recordBuff.buff.clear();
// clear intracellular info
// intraBuff.init();
if ( simulatorParser.backgroundFrequency > 0.0 )
{
for ( int i = 0; i < neurons.length; i++ )
{
if ( !neurons [ i ].isSensory ( ) )
{
final double inputEventTime
= -Math.log ( Cnsran.ran2 ( seed ) )
/ simulatorParser.backgroundFrequency;
final Synapse synapse = modelFactory.createSynapse (
base + i,
( byte ) simulatorParser.bChannel,
( float ) simulatorParser.backgroundStrength );
final PInputEvent pInputEvent = new PInputEvent (
inputEventTime,
synapse,
-1 ); // sourceId
poissonQueue.insertItem ( pInputEvent );
}
}
}
// put the other sources of inputs
final Stimulus [ ] stimuli = subExp.stimuli;
final int stimulusCount = stimuli.length;
for ( int i = 0; i < stimulusCount; i++ )
{
final Stimulus stimulus = stimuli [ i ];
// unify the seed
stimulus.seed = seed;
final ArrayList<PInputEvent>
pInputEventArrayList = stimulus.init ( i );
for ( final PInputEvent pInputEvent : pInputEventArrayList )
{
poissonQueue.insertItem ( pInputEvent );
}
}
final int
neuronsLengthMinusOne = neurons.length - 1;
for ( int i = 0; i < neuronsLengthMinusOne; i++ )
{
// all neurons will be initialized
final Neuron neuron = neurons [ i ];
neuron.init (
subExpId,
trialId,
seed,
this,
base + i );
// if(neurons[i].isSensory())
// {
// // sensory neuron send spikes to the other neurons
//
// fireQueue.insertItem (
// new FireEvent ( i + base, 0.0 ) );
//
// // sensory neuron send spikes to the other neurons
//
// fireQueue.insertItem (
// new FireEvent ( i + base, neurons [ i ].updateFire ( ) ) );
// }
// else
// {
// }
}
// p.println("neurons number: "+neurons.length);
if ( info != null )
{
if ( info.numTasks == 1
&& experiment.recorder.intraEle.size ( ) == 0 )
{
// sensory neuron send spikes to the other neurons
fireQueue.insertItem (
new FireEvent (
neurons.length - 1 + base,
experiment.subExp [ subExpId ].trialLength ) );
}
else
{
// sensory neuron send spikes to the other neurons
fireQueue.insertItem (
new FireEvent (
neurons.length - 1 + base,
0.0 ) );
}
}
}
}
/***********************************************************************
* One time initialization, initialize the structure to store the times.
***********************************************************************/
public void initMain ( )
////////////////////////////////////////////////////////////////////////
{
// double tmp_time;
// minimum delay is 1ms
// minDelay = 0.001;
// fireQueue = new TreeQueue<FireEvent>();
stop = false;
if ( info != null )
{
localTime = new double [ info.numTasks ];
}
// send initial input spikes from the sensory neuron to all the
// neurons in the network
/*
for(int i= 1; i< neurons.length; i++)
{
// 5Hz background input
tmp_time=-Math.log(Cnsran.ran2(idum))/5.0;
//sensory neuron send spikes to the other neurons
inputQueue.insertItem( new InputEvent(0,tmp_time,i,1e-10));
}
inputQueue.show();
*/
/*
tmp_time = (-Math.log(Cnsran.ran2(idum))/freq);
for(int i=0; i<info.endIndex.length; i++)
{
if(! (neurons[info.endIndex[i]] instanceof BKPoissonNeuron))
{
//sensory neuron send spikes to the other neurons
fireQueue.insertItem( new FireEvent(info.endIndex[i]+base,tmp_time));
}
}
*/
}
/***********************************************************************
* process the event from fireQueue
*
* @param
* firstFire
***********************************************************************/
/*
public void fireProcess(FireEvent firstFire)
////////////////////////////////////////////////////////////////////////
{
double tmp_firetime;
//note the sensory neuron will never fire
//p.println("fire: "+firstFire);
//if(firstFire.index!=0)inputQueue.show();
if(firstFire.index>1000 && firstFire.index<1100)
{
System.out.println("fire: "+firstFire);
}
//System.out.println("fire: "+firstFire);
//first send out the spikes
for(int i=0 ; i < (neurons[firstFire.index].getAxon()).branches.length;
i++)
{
// if(firstFire.index==0)
// {
// System.out.println (
// neurons [ firstFire.index ]
// .getAxon ( ).branches [ i ].synapses.length );
// }
inputQueue.insertItem (
new InputEvent (
firstFire.time
+ ( neurons [ firstFire.index ].getAxon ( ) ).branches [ i ]
.delay,
( neurons [ firstFire.index ].getAxon ( ) ).branches [ i ],
firstFire.index ) );
}
double timeOfNextEvent;
// neuron do fire
if( (timeOfNextEvent=neurons[firstFire.index].updateFire()) >=0.0 )
{
tmp_firetime=firstFire.time+ timeOfNextEvent;
//neurons[firstFire.index].timeOfFire();
neurons[firstFire.index].setTimeOfNextFire(tmp_firetime);
//insert this into the new firing queue;
fireQueue.insertItem(new FireEvent(firstFire.index, tmp_firetime));
}
else
{
//if the neuron doesn't fire
neurons[firstFire.index].setTimeOfNextFire(-1);
}
fireQueue.deleteItem(firstFire); //delete this item
}
*/
/***********************************************************************
* Process the event from fireQueue in parallel.
***********************************************************************/
public void pFireProcess ( final FireEvent firstFireEvent )
throws jpvmException, Exception
////////////////////////////////////////////////////////////////////////
{
final int adjustedNeuronIndex = firstFireEvent.index - base;
final Neuron neuron = neurons [ adjustedNeuronIndex ];
/*
p.println("fire t:"+firstFire.time+" index:"+firstFire.index);
fireQueue.show(p);
inputQueue.show(p);
poissonQueue.show(p);
*/
double tmp_firetime;
// only neuron really fires
if ( neuron.realFire ( ) )
{
// int host;
// if the neuron is recordable
if ( neuron.getRecord ( ) )
{
// p.println(firstFire.index+" recorded");
recordBuff.buff.add (
new NetRecordSpike (
firstFireEvent.time,
firstFireEvent.index ) );
}
/*
if ( firstFire.index != neurons.length + base - 1
&& firstFire.index > 1000
&& firstFire.index < 1100 ) //don't record special neurons
{
jpvmBuffer buff = new jpvmBuffer ( );
buff.pack (
new NetRecordSpike (
localTime,
firstFire.time,
firstFire.index ) );
info.jpvm.pvm_send (
buff,
info.parent,
NetMessageTag.gatherFire );
}
*/
// first send out the spikes
// int i=0;
// try
// {
// System.out.println (
// "neuron:"+(firstFire.index-base)+" fire:"+firstFire.time);
long target = neuron.getTHost ( );
for ( int i = 0; i < info.numTasks; i++ )
{
if ( ( target & ( 1L << i ) ) != 0 ) // it has target at host i
{
if ( i == info.idIndex ) // localhost
{
final Integer
axonIndex = Integer.valueOf ( firstFireEvent.index );
final Axon axon = axons.get ( axonIndex );
final int axonBranchesLength = axon.branches.length;
for ( int iter = 0; iter < axonBranchesLength; iter++ )
{
final Branch branch = axon.branches [ iter ];
inputEventSlot.offer (
new InputEvent (
firstFireEvent.time + branch.delay,
branch,
firstFireEvent.index ) );
}
}
else // remote host
{
spikeBuffers [ i ].buff.add (
new NetMessage (
firstFireEvent.time,
firstFireEvent.index ) );
}
}
}
// }
// catch ( ArrayIndexOutOfBoundsException e )
// {
// p.println ( "firstFire.index-base:"+firstFire.index+"-"+base
// +"="+(firstFire.index-base)+" uplimit"+neurons.length
// +" branch_length"
// +neurons[firstFire.index-base].getAxon().branches.length
// +" curr "+i + "synapse empty"
// + ( ( neurons [ firstFire.index - base ].getAxon ( ) )
// .branches[i].synapses==null)
// + " syn:"
// + ( ( neurons [ firstFire.index - base ].getAxon ( ) )
// .branches[i].synapses.length ) );
//
// e.printStackTrace ( p );
// }
}
double timeOfNextEvent;
// neuron do fire
if ( ( timeOfNextEvent = neuron.updateFire ( ) ) >= 0 )
{
tmp_firetime = firstFireEvent.time + timeOfNextEvent;
// neurons[firstFire.index-base].timeOfFire();
// insert this into the new firing queue;
fireQueue.insertItem (
new FireEvent (
firstFireEvent.index,
tmp_firetime ) );
neuron.setTimeOfNextFire ( tmp_firetime );
}
else
{
// if the neuron doesn't fire
neuron.setTimeOfNextFire ( -1 );
}
// delete this item
fireQueue.deleteItem ( firstFireEvent );
}
@SuppressWarnings("unused")
@Deprecated
public void pMainProcess (
FireEvent firstFire,
double freq,
double weight,
Seed seed)
////////////////////////////////////////////////////////////////////////
{
//
}
/***********************************************************************
* process the event from (internal) inputQueue
*
* @param firstInput
***********************************************************************/
@Deprecated
public void inputProcess ( InputEvent firstInput )
////////////////////////////////////////////////////////////////////////
{
double tmp_firetime;
//System.out.println("input: "+firstInput);
// first delete the false prediction
//System.out.println("input:"+firstInput);
for ( int i = 0; i < firstInput.branch.synapses.length ; i++)
{
// if ( firstInput.branch.synapses [ i ].to == 8300 )
// {
// System.out.println("find trace"+firstInput+" 8300");
// }
// if last time predicts the neuron will fire in future
// TODO: requires cleanup
if ( neurons [
firstInput.branch.synapses [ i ].getTargetNeuronIndex ( ) ]
.getTimeOfNextFire ( ) != -1 )
{
// System.out.println (
// new FireEvent (
// firstInput.branch.synapses[i].to,
// neurons [ firstInput.branch.synapses [ i ].to ]
// .getTimeOfNextFire ( ) ) );
fireQueue.deleteItem (
new FireEvent (
firstInput.branch.synapses [ i ].getTargetNeuronIndex ( ),
neurons [ firstInput.branch.synapses [ i ].getTargetNeuronIndex ( ) ]
.getTimeOfNextFire ( ) ) );
}
double timeOfNextEvent;
// neuron do fire
if ( ( timeOfNextEvent
= neurons [ firstInput.branch.synapses [ i ]
.getTargetNeuronIndex ( ) ].updateInput (
firstInput.time,
firstInput.branch.synapses [ i ] ) ) >= 0.0 )
{
tmp_firetime = firstInput.time + timeOfNextEvent;
//neurons[firstInput.branch.synapses[i].to].timeOfFire();
neurons [ firstInput.branch.synapses [ i ]
.getTargetNeuronIndex ( ) ]
.setTimeOfNextFire ( tmp_firetime );
//insert this into the new firing queue;
fireQueue.insertItem (
new FireEvent (
firstInput.branch.synapses [ i ].getTargetNeuronIndex ( ),
tmp_firetime));
}
else
{
// if the neuron doesn't fire
neurons [ firstInput.branch.synapses [ i ]
.getTargetNeuronIndex ( ) ]
.setTimeOfNextFire ( -1 );
}
}
// delete this item
inputQueue.deleteItem ( firstInput );
}
/***********************************************************************
* poisson input process
***********************************************************************/
@Deprecated
public void poissonProcess(PInputEvent poiInput)
////////////////////////////////////////////////////////////////////////
{
double tmp_firetime;
// if last time predicts the neuron will fire in future
if ( neurons [ poiInput.synapse.getTargetNeuronIndex ( ) ]
.getTimeOfNextFire ( ) != -1 )
{
// System.out.println (
// new FireEvent (
// firstInput.branch.synapses [ i ].to,
// neurons [ firstInput.branch.synapses [ i ].to ]
// .getTimeOfNextFire ( ) ) );
fireQueue.deleteItem (
new FireEvent (
poiInput.synapse.getTargetNeuronIndex ( ),
neurons [ poiInput.synapse.getTargetNeuronIndex ( ) ]
.getTimeOfNextFire ( ) ) );
}
double timeOfNextEvent;
// neuron do fire
if ( ( timeOfNextEvent
= neurons [ poiInput.synapse.getTargetNeuronIndex ( ) ]
.updateInput (
poiInput.time,
poiInput.synapse ) ) >=0.0 )
{
tmp_firetime = poiInput.time + timeOfNextEvent;
// neurons[poiInput.synapse.to].timeOfFire();
neurons [ poiInput.synapse.getTargetNeuronIndex ( ) ]
.setTimeOfNextFire ( tmp_firetime );
// insert this into the new firing queue;
fireQueue.insertItem (
new FireEvent (
poiInput.synapse.getTargetNeuronIndex ( ),
tmp_firetime ) );
}
else
{
// if the neuron doesn't fire
neurons [ poiInput.synapse.getTargetNeuronIndex ( ) ]
.setTimeOfNextFire ( -1 );
}
poissonQueue.insertItem (
new PInputEvent (
poiInput.time + ( -Math.log ( Cnsran.ran2 ( seed ) )
/ simulatorParser.backgroundFrequency ),
poiInput.synapse,
-1 ) );
// delete this item
poissonQueue.deleteItem ( poiInput );
}
/***********************************************************************
* poisson input process (external input) in parallel
***********************************************************************/
public void pPoissonProcess ( PInputEvent poiInput )
////////////////////////////////////////////////////////////////////////
{
final int targetNeuronIndex
= poiInput.synapse.getTargetNeuronIndex ( ) - base;
final Neuron targetNeuron = neurons [ targetNeuronIndex ];
// p.println("t:"+poiInput.time+" sourceID:"+poiInput.sourceId
// +" id"+poiInput.synapse.to+" syn:"+poiInput.synapse);
// p.flush();
// fireQueue.show(p);
// inputQueue.show(p);
// poissonQueue.show(p);
final double timeOfNextFire = targetNeuron.getTimeOfNextFire ( );
if ( timeOfNextFire != -1 )
{
// if last time predicts the neuron will fire in future
fireQueue.deleteItem (
new FireEvent (
poiInput.synapse.getTargetNeuronIndex ( ),
targetNeuron.getTimeOfNextFire ( ) ) );
}
final double
timeOfNextEvent = targetNeuron.updateInput (
poiInput.time,
poiInput.synapse );
// neuron do fire
if ( timeOfNextEvent >= 0.0 )
{
// p.println("neuron fire");
// p.flush();
final double
tmp_firetime = poiInput.time + timeOfNextEvent;
//neurons[poiInput.synapse.to-base].timeOfFire();
// insert this into the new firing queue
fireEventSlot.offer (
new FireEvent (
poiInput.synapse.getTargetNeuronIndex ( ),
tmp_firetime ) );
targetNeuron.setTimeOfNextFire ( tmp_firetime );
// p.println("neuron time called");
// p.flush();
}
else
{
// p.println("neuron doesn't fire");
// p.flush();
// if the neuron doesn't fire
targetNeuron.setTimeOfNextFire ( -1 );
}
// p.println("input is updated");
// p.flush();
if ( poiInput.sourceId == -1 )
{
poissonQueue.insertItem (
new PInputEvent (
poiInput.time + ( -Math.log ( Cnsran.ran2 ( seed ) )
/ simulatorParser.backgroundFrequency ),
poiInput.synapse,
-1 ) );
}
else
{
final SubExp
subExp = experiment.subExp [ subExpId ];
final Stimulus
stimulus = subExp.stimuli [ poiInput.sourceId ];
final double timeOfNext
= stimulus.getNextTime ( poiInput.time );
if ( timeOfNext >= 0 )
{
//p.println("t:"+timeOfNext+" sourceID:"+poiInput.sourceId
//+" id"+poiInput.synapse.to);
poissonQueue.insertItem (
new PInputEvent (
timeOfNext,
poiInput.synapse,
poiInput.sourceId ) );
}
}
// delete this item
poissonQueue.deleteItem ( poiInput );
}
/***********************************************************************
* Process the event from inputQueue in parallel.
***********************************************************************/
public void pInputProcess ( final InputEvent firstInputEvent )
////////////////////////////////////////////////////////////////////////
{
// p.println("INPUT");
// fireQueue.show(p);
// inputQueue.show(p);
// poissonQueue.show(p);
for ( final Synapse synapse : firstInputEvent.branch.synapses )
{
// if(firstInput.branch.synapses[i].to==8300)
// p.println("find trace"+firstInput+" 8300");
// TODO: rename to adjustedTargetNeuronIndex
final int
targetNeuronIndex = synapse.getTargetNeuronIndex ( ) - base;
final Neuron targetNeuron = neurons [ targetNeuronIndex ];
// if last time predicts the neuron will fire in future
final double timeOfNextFire = targetNeuron.getTimeOfNextFire ( );
if ( timeOfNextFire != -1 )
{
fireQueue.deleteItem (
new FireEvent (
synapse.getTargetNeuronIndex ( ),
timeOfNextFire ) );
}
final double timeOfNextEvent = targetNeuron.updateInput (
firstInputEvent.time,
synapse );
// neuron do fire
if ( timeOfNextEvent >= 0.0 )
{
final double
tmp_firetime = firstInputEvent.time + timeOfNextEvent;
// neurons[firstInput.branch.synapses[i].to-base].timeOfFire();
// insert this into the new firing queue;
fireQueue.insertItem (
new FireEvent (
synapse.getTargetNeuronIndex ( ),
tmp_firetime ) );
targetNeuron.setTimeOfNextFire ( tmp_firetime );
}
else
{
// if the neuron doesn't fire
targetNeuron.setTimeOfNextFire ( -1 );
}
}
// delete this item
inputQueue.deleteItem ( firstInputEvent );
}
/*
public void testRun()
////////////////////////////////////////////////////////////////////////
{
FireEvent firstFire;
InputEvent firstInput;
PInputEvent poiInput;
double minTime;
double fireTime, inputTime, pInputTime;
// System.out.println("before running...");
// inputQueue.show();
while(!stop)
{
// take out the first fire element
firstFire = fireQueue.firstItem();
// take out the first input element
firstInput = inputQueue.firstItem();
// take out the first poisson input element
poiInput = poissonQueue.firstItem();
// System.out.println("running...");
if(firstFire != null)
{
fireTime=firstFire.time;
}
else
{
fireTime=Double.MAX_VALUE;
}
if(firstInput != null)
{
inputTime=firstInput.time;
}
else
{
inputTime=Double.MAX_VALUE;
}
if(poiInput != null)
{
pInputTime=poiInput.time;
}
else
{
pInputTime=Double.MAX_VALUE;
}
minTime = ( fireTime < inputTime? fireTime: inputTime);
minTime = (minTime < pInputTime? minTime: pInputTime);
if( firstFire != null && minTime == firstFire.time) //fire event
{
// System.out.println("fire.."+firstFire);
fireProcess(firstFire);
}
// input event
else if ( firstInput !=null && minTime == firstInput.time)
{
// System.out.println("input..");
inputProcess(firstInput);
}
// poissoninput event
else if ( poiInput !=null && minTime == poiInput.time)
{
// System.out.println("background: "+poiInput.synapse.to);
poissonProcess(poiInput);
}
}
}
*/
////////////////////////////////////////////////////////////////////////
// private methods
////////////////////////////////////////////////////////////////////////
private void clearModulationFactors ( )
////////////////////////////////////////////////////////////////////////
{
if ( modulatedSynapseSeq == null )
{
return;
}
final int size = modulatedSynapseSeq.size ( );
for ( int i = 0; i < size; i++ )
{
final ModulatedSynapse
modulatedSynapse = modulatedSynapseSeq.get ( i );
modulatedSynapse.clearModulationFactors ( );
}
}
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
}