001 package cnslab.cnsnetwork; 002 003 import java.io.*; 004 import java.util.*; 005 006 import org.slf4j.Logger; 007 import org.slf4j.LoggerFactory; 008 009 import jpvm.jpvmException; 010 import jpvm.jpvmTaskId; 011 012 import cnslab.cnsmath.*; 013 import edu.jhu.mb.ernst.engine.DiscreteEvent; 014 import edu.jhu.mb.ernst.engine.DiscreteEventQueue; 015 import edu.jhu.mb.ernst.model.ModelFactory; 016 import edu.jhu.mb.ernst.model.ModulatedSynapse; 017 import edu.jhu.mb.ernst.model.Synapse; 018import edu.jhu.mb.ernst.util.seq.Seq; 019 import edu.jhu.mb.ernst.util.slot.ErnstQueueSlot; 020import edu.jhu.mb.ernst.util.slot.Slot; 021 022 /*********************************************************************** 023 * Network structure to organize all the small pieces (neurons, layers, 024 * axons, recorders, etc.) together. 025 * 026 * @version 027 * $Date: 2012-08-04 13:43:22 -0500 (Sat, 04 Aug 2012) $ 028 * $Rev: 104 $ 029 * $Author: croft $ 030 * @author 031 * Yi Dong 032 * @author 033 * David Wallace Croft 034 ***********************************************************************/ 035 public class Network 036 //////////////////////////////////////////////////////////////////////// 037 //////////////////////////////////////////////////////////////////////// 038 { 039 040 private static final Class<Network> 041 CLASS = Network.class; 042 043 private static final Logger 044 LOGGER = LoggerFactory.getLogger ( CLASS ); 045 046 // 047 048 public int 049 countTrial, 050 expIdBack, 051 trialIdBack; 052 053 public Experiment experiment; 054 055 /** Keep track of current simulated subExp id */ 056 public int subExpId; 057 058 /** Keep track of current Trials. */ 059 public int trialId; 060 061 /** Size of Xedge */ 062 public int xEdge; 063 064 /** Size of Yedge */ 065 public int yEdge; 066 067 /** a data structure map "pre,x,y,suf" to neuron index */ 068 public Map<String, Integer> cellmap; 069 070 /** the seed value for this network */ 071 public Seed seed; 072 073 /** the system background firing rates */ 074 public SimulatorParser simulatorParser; 075 076 /** the minimum synaptic delay */ 077 public double minSynapticDelay; 078 079 /** for the output of the slave hosts */ 080 public PrintStream p; 081 082 /** the parallel machine informations */ 083 public JpvmInfo info; 084 085 /** used by the root host to monitor other host's time */ 086 public double [ ] localTime; 087 088 /** spike buffer to store the neuron spikes which needs to be sented */ 089 public SpikeBuffer [ ] spikeBuffers; 090 091 /** used for keep record of received spikes */ 092 public int [ ] received; 093 094 /** recorded intracellular info */ 095 public IntraRecBuffer intraRecBuffers; 096 097 /** recorded info buffer */ 098 public RecordBuffer recordBuff; 099 100 /** neuron index base, the real index is index+base */ 101 public int base; 102 103 /** the root broadcasting time */ 104 public double rootTime; 105 106 /** the end of Trial time */ 107 public double endOfTrial; 108 109 /** An array of neurons used in current Nethosts */ 110 public Neuron [ ] neurons; 111 112 /** A data structure mapping neuron id to the neuron's Axon. */ 113 public Map<Integer, Axon> axons; 114 115 /** Store the recorded data. */ 116 public RecorderData recorderData; 117 118 /** flag for the computation and communication threads to stop */ 119 public boolean stop; 120 121 /** Flag to indicate whether the trial is done or not */ 122 public boolean trialDone; 123 124 /** trial start flag */ 125 public boolean startSig; 126 127 /** flag for trial end */ 128 public boolean spikeState = true; 129 130 // protected final instance variables 131 132 protected final ModelFactory modelFactory; 133 134 protected final DiscreteEventQueue discreteEventQueue; 135 136 // protected non-final instance variables 137 138 /** The neuron fire queue */ 139 protected Queue<FireEvent> fireQueue; 140 141 /** The (internal) input spike queue */ 142 protected Queue<InputEvent> inputQueue; 143 144 /** The (external) input queue */ 145 // used for poisson background firing event queue 146 protected Queue<PInputEvent> poissonQueue; 147 148 // private instance variables 149 150 private final Seq<ModulatedSynapse> modulatedSynapseSeq; 151 152 // 153 154 private Slot<FireEvent> fireEventSlot; 155 156 private Slot<InputEvent> inputEventSlot; 157 158 private Slot<PInputEvent> pInputEventSlot; 159 160 //////////////////////////////////////////////////////////////////////// 161 // constructor methods 162 //////////////////////////////////////////////////////////////////////// 163 164 public Network ( 165 final ModelFactory modelFactory, 166 final DiscreteEventQueue discreteEventQueue, 167 final Seq<ModulatedSynapse> modulatedSynapseSeq, 168 final Neuron [ ] neurons, 169 final Map<Integer, Axon> axons, 170 final double minSynapticDelay, 171 final SimulatorParser simulatorParser, 172 final Seed seed ) 173 //////////////////////////////////////////////////////////////////////// 174 { 175 this.modelFactory = modelFactory; 176 177 this.discreteEventQueue = discreteEventQueue; 178 179 this.modulatedSynapseSeq = modulatedSynapseSeq; 180 181 this.neurons = neurons; 182 183 this.axons = axons; 184 185 this.minSynapticDelay = minSynapticDelay; 186 187 this.simulatorParser = simulatorParser; 188 189 this.seed = seed; 190 191 this.recorderData = new RecorderData ( ); 192 } 193 194 public Network ( 195 final ModelFactory modelFactory, 196 final DiscreteEventQueue discreteEventQueue, 197 final Seq<ModulatedSynapse> modulatedSynapseSeq, 198 final Neuron [ ] neurons, 199 final Map<Integer, Axon> axons, 200 final JpvmInfo info, 201 final int base, 202 final double minSynapticDelay, 203 final SimulatorParser simulatorParser, 204 final Seed seed, 205 final Experiment experiment ) 206 //////////////////////////////////////////////////////////////////////// 207 { 208 this.modelFactory = modelFactory; 209 210 this.discreteEventQueue = discreteEventQueue; 211 212 this.modulatedSynapseSeq = modulatedSynapseSeq; 213 214 this.neurons = neurons; 215 216 this.axons = axons; 217 218 this.info = info; 219 220 this.base = base; 221 222 this.minSynapticDelay = minSynapticDelay; 223 224 this.simulatorParser = simulatorParser; 225 226 this.seed = seed; 227 228 this.experiment = experiment; 229 230 this.recorderData = new RecorderData ( ); 231 } 232 233 public Network ( 234 final ModelFactory modelFactory, 235 final DiscreteEventQueue discreteEventQueue, 236 final Seq<ModulatedSynapse> modulatedSynapseSeq, 237 final Experiment experiment, 238 final JpvmInfo info, 239 final int base, 240 final double minSynapticDelay, 241 final SimulatorParser simulatorParser, 242 final Seed seed ) 243 //////////////////////////////////////////////////////////////////////// 244 { 245 this.modelFactory = modelFactory; 246 247 this.discreteEventQueue = discreteEventQueue; 248 249 this.modulatedSynapseSeq = modulatedSynapseSeq; 250 251 this.experiment = experiment; 252 253 this.info = info; 254 255 this.base = base; 256 257 this.minSynapticDelay = minSynapticDelay; 258 259 this.simulatorParser = simulatorParser; 260 261 this.seed = seed; 262 263 this.recorderData = new RecorderData ( ); 264 } 265 266 //////////////////////////////////////////////////////////////////////// 267 // accessor methods 268 //////////////////////////////////////////////////////////////////////// 269 270 public DiscreteEventQueue getDiscreteEventQueue ( ) 271 //////////////////////////////////////////////////////////////////////// 272 { 273 return discreteEventQueue; 274 } 275 276 public synchronized double getLocalTime ( final int i ) 277 //////////////////////////////////////////////////////////////////////// 278 { 279 return localTime [ i ]; 280 } 281 282 public Slot<FireEvent> getFireEventSlot ( ) 283 //////////////////////////////////////////////////////////////////////// 284 { 285 return fireEventSlot; 286 } 287 288 public FireEvent getFirstFireEvent ( ) 289 //////////////////////////////////////////////////////////////////////// 290 { 291 return fireQueue.firstItem ( ); 292 } 293 294 public InputEvent getFirstInputEvent ( ) 295 //////////////////////////////////////////////////////////////////////// 296 { 297 return inputQueue.firstItem ( ); 298 } 299 300 public PInputEvent getFirstPInputEvent ( ) 301 //////////////////////////////////////////////////////////////////////// 302 { 303 return poissonQueue.firstItem ( ); 304 } 305 306 public Slot<InputEvent> getInputEventSlot ( ) 307 //////////////////////////////////////////////////////////////////////// 308 { 309 return inputEventSlot; 310 } 311 312 public Slot<PInputEvent> getPInputEventSlot ( ) 313 //////////////////////////////////////////////////////////////////////// 314 { 315 return pInputEventSlot; 316 } 317 318 //////////////////////////////////////////////////////////////////////// 319 // mutator methods 320 //////////////////////////////////////////////////////////////////////// 321 322 public void clearQueues ( ) 323 //////////////////////////////////////////////////////////////////////// 324 { 325 fireQueue .clear ( ); 326 327 inputQueue .clear ( ); 328 329 poissonQueue.clear ( ); 330 331 discreteEventQueue.clear ( ); 332 } 333 334 /*********************************************************************** 335 * set a new value to localTime 336 * 337 * @param localTime 338 * the new value to be used 339 ***********************************************************************/ 340 public synchronized void setLocalTime ( 341 final double localTime, 342 final int i ) 343 //////////////////////////////////////////////////////////////////////// 344 { 345 this.localTime [ i ] = localTime; 346 } 347 348 //////////////////////////////////////////////////////////////////////// 349 //////////////////////////////////////////////////////////////////////// 350 351 /*********************************************************************** 352 * stop the testRun(); 353 ***********************************************************************/ 354 public void stopRun ( ) 355 //////////////////////////////////////////////////////////////////////// 356 { 357 stop = true; 358 } 359 360 /*********************************************************************** 361 * Initializes the Network. 362 * fill up the first item for inputQueue, fireQueue, poissonQueue 363 * (the implementation of the queue is changed here), 364 * Initialized SyncNeuron (Index is the number of neurons). 365 ***********************************************************************/ 366 public void initNet ( ) 367 //////////////////////////////////////////////////////////////////////// 368 { 369 // subExpId=0; //the first subExp 370 // trialId=-1; // the first trial; 371 372 // double tmp_time; 373 374 // minDelay = 0.001; //minimum delay is 1ms 375 // inputQueue = new PriQueue<InputEvent>(); // assign the queue 376 // inputQueue = new FiboQueue<InputEvent>(); // assign the queue 377 // inputQueue = new TreeQueue<InputEvent>(); // assign the queue 378 379 // assign the queue 380 381 inputQueue = new MTreeQueue<InputEvent> ( ); 382 383 inputEventSlot = new ErnstQueueSlot<InputEvent> ( inputQueue ); 384 385 // fireQueue = new TreeQueue<FireEvent>(); 386 387 fireQueue = new MTreeQueue<FireEvent> ( ); 388 389 fireEventSlot = new ErnstQueueSlot<FireEvent> ( fireQueue ); 390 391 // if(bFreq>0.0) 392 // { 393 394 // assign the queue 395 396 poissonQueue = new MTreeQueue<PInputEvent> ( ); 397 398 pInputEventSlot = new ErnstQueueSlot<PInputEvent> ( poissonQueue ); 399 400 // } 401 402 stop = false; 403 404 if ( info != null ) 405 { 406 spikeBuffers = new SpikeBuffer [ info.numTasks ]; 407 408 // adding the clock neuron at the end of neuron list 409 410 neurons [ neurons.length - 1 ] = new SYNNeuron ( this ); 411 412 for ( int i = 0; i < info.numTasks; i++ ) 413 { 414 spikeBuffers [ i ] = new SpikeBuffer ( ); 415 } 416 417 recordBuff = new RecordBuffer ( ); 418 419 received = new int [ info.numTasks ]; 420 421 for ( int iter = 0; iter < info.numTasks; iter++ ) 422 { 423 // leave mark here 424 425 received [ iter ] = 1; 426 } 427 428 intraRecBuffers 429 = new IntraRecBuffer ( experiment.recorder.intraNeurons ( ) ); 430 431 // send initial input spikes from the sensory neuron to all the 432 // neurons in the network 433 434 /* 435 for(int i= 1; i< neurons.length; i++) 436 { 437 // 5Hz background input 438 tmp_time=-Math.log(Cnsran.ran2(idum))/5.0; 439 // sensory neuron send spikes to the other neurons 440 inputQueue.insertItem( new InputEvent(0,tmp_time,i,1e-10)); 441 } 442 inputQueue.show(); 443 */ 444 /* 445 if(bFreq>0.0) 446 { 447 // poissonQueue = new PriQueue<PInputEvent>(); // assign the queue 448 poissonQueue = new MTreeQueue<PInputEvent>(); // assign the queue 449 // poissonQueue = new TreeQueue<PInputEvent>(); // assign the queue 450 for(int i=0; i<neurons.length; i++) 451 { 452 if(!neurons[i].isSensory()) 453 { 454 poissonQueue.insertItem ( 455 new PInputEvent ( 456 -Math.log ( Cnsran.ran2 ( idum ) ) / bFreq, 457 new Synapse ( base+i, 1e-10, 0 ), 458 0 ) ); 459 } 460 } 461 } 462 */ 463 /* 464 465 for(int i=0; i<neurons.length; i++) 466 { 467 if(neurons[i].isSensory()) 468 { 469 // sensory neuron send spikes to the other neurons 470 fireQueue.insertItem( new FireEvent(i+base,0.0)); 471 } 472 } 473 */ 474 475 try 476 { 477 478 final jpvmTaskId parentJpvmTaskId = info.parentJpvmTaskId; 479 480 final String 481 host = parentJpvmTaskId == null 482 ? "null-task-id" : parentJpvmTaskId.getHost ( ); 483 484 final FileOutputStream out = new FileOutputStream ( 485 "log/" 486 + host 487 + "_myfile" 488 + info.idIndex 489 + ".txt" ); 490 491 p = new PrintStream ( out ); 492 493 // p.println(base+neurons[neurons.length-1].toString()); 494 495 p.println ( "Logfile start" ); 496 } 497 catch ( final Exception e ) 498 { 499 e.printStackTrace ( ); 500 501 LOGGER.error ( e.getMessage ( ), e ); 502 } 503 504 final String curDir = System.getProperty ( "user.dir" ); 505 506 p.println ( curDir ); 507 508 //added 509 /* 510 for(int iter=0;iter<info.numTasks;iter++) 511 { 512 while(!received[iter].empty()) 513 { 514 received[iter].pop(); 515 } 516 received[iter].push(new Object()); 517 } 518 */ 519 //added over 520 } 521 522 // init(); 523 } 524 525 /*********************************************************************** 526 * Initialize the queues, put the first element into each of the queues. 527 * 528 * Called from PRun.run(). 529 ***********************************************************************/ 530 public void init ( ) 531 //////////////////////////////////////////////////////////////////////// 532 { 533 // I added this as I was worried that the queues were not being 534 // cleared between repetitions of subexperiments. 535 536 // But then again, maybe there are special elements that need to 537 // stay in there for distributed computing. I need to look into the 538 // differences between init() and initNet() and when they are called. 539 540 // clearQueues ( ); 541 542 discreteEventQueue.clear ( ); 543 544 final SubExp subExp = experiment.subExp [ subExpId ]; 545 546 final Collection<DiscreteEvent> 547 discreteEventCollection = subExp.getDiscreteEventCollection ( ); 548 549 if ( discreteEventCollection != null ) 550 { 551 discreteEventQueue.addAll ( discreteEventCollection ); 552 } 553 554 clearModulationFactors ( ); 555 556 // double tmp_time; 557 558 // minimum delay is 1ms 559 // minDelay = 0.001; 560 561 stop = false; 562 563 // trialDone=false; 564 565 spikeState = true; 566 567 /* this modification make old simulator done's run any more 568 569 trialId++; 570 if(trialId == exp.subExp[subExpId].repetition) 571 { 572 trialId =0; 573 subExpId++; 574 } 575 */ 576 577 // p.println("sub "+subExpId+ "tri: "+trialId); 578 579 // only initialize when subExp is within the range 580 581 if ( subExpId < experiment.subExp.length ) 582 { 583 /* 584 for(int iter=0;iter<info.numTasks;iter++) 585 { 586 while(!received[iter].empty()) 587 { 588 received[iter].pop(); 589 } 590 591 received[iter].push(new Object()); 592 } 593 */ 594 595 if ( info != null ) 596 { 597 for ( int i = 0; i < info.numTasks; i++ ) 598 { 599 spikeBuffers [ i ].buff.clear ( ); 600 } 601 } 602 603 // recordBuff.buff.clear(); 604 605 // clear intracellular info 606 607 // intraBuff.init(); 608 609 if ( simulatorParser.backgroundFrequency > 0.0 ) 610 { 611 for ( int i = 0; i < neurons.length; i++ ) 612 { 613 if ( !neurons [ i ].isSensory ( ) ) 614 { 615 final double inputEventTime 616 = -Math.log ( Cnsran.ran2 ( seed ) ) 617 / simulatorParser.backgroundFrequency; 618 619 final Synapse synapse = modelFactory.createSynapse ( 620 base + i, 621 ( byte ) simulatorParser.bChannel, 622 ( float ) simulatorParser.backgroundStrength ); 623 624 final PInputEvent pInputEvent = new PInputEvent ( 625 inputEventTime, 626 synapse, 627 -1 ); // sourceId 628 629 poissonQueue.insertItem ( pInputEvent ); 630 } 631 } 632 } 633 634 // put the other sources of inputs 635 636 final Stimulus [ ] stimuli = subExp.stimuli; 637 638 final int stimulusCount = stimuli.length; 639 640 for ( int i = 0; i < stimulusCount; i++ ) 641 { 642 final Stimulus stimulus = stimuli [ i ]; 643 644 // unify the seed 645 646 stimulus.seed = seed; 647 648 final ArrayList<PInputEvent> 649 pInputEventArrayList = stimulus.init ( i ); 650 651 for ( final PInputEvent pInputEvent : pInputEventArrayList ) 652 { 653 poissonQueue.insertItem ( pInputEvent ); 654 } 655 } 656 657 final int 658 neuronsLengthMinusOne = neurons.length - 1; 659 660 for ( int i = 0; i < neuronsLengthMinusOne; i++ ) 661 { 662 // all neurons will be initialized 663 664 final Neuron neuron = neurons [ i ]; 665 666 neuron.init ( 667 subExpId, 668 trialId, 669 seed, 670 this, 671 base + i ); 672 673 // if(neurons[i].isSensory()) 674 // { 675 // // sensory neuron send spikes to the other neurons 676 // 677 // fireQueue.insertItem ( 678 // new FireEvent ( i + base, 0.0 ) ); 679 // 680 // // sensory neuron send spikes to the other neurons 681 // 682 // fireQueue.insertItem ( 683 // new FireEvent ( i + base, neurons [ i ].updateFire ( ) ) ); 684 // } 685 // else 686 // { 687 // } 688 } 689 690 // p.println("neurons number: "+neurons.length); 691 692 if ( info != null ) 693 { 694 if ( info.numTasks == 1 695 && experiment.recorder.intraEle.size ( ) == 0 ) 696 { 697 // sensory neuron send spikes to the other neurons 698 699 fireQueue.insertItem ( 700 new FireEvent ( 701 neurons.length - 1 + base, 702 experiment.subExp [ subExpId ].trialLength ) ); 703 } 704 else 705 { 706 // sensory neuron send spikes to the other neurons 707 708 fireQueue.insertItem ( 709 new FireEvent ( 710 neurons.length - 1 + base, 711 0.0 ) ); 712 } 713 } 714 } 715 } 716 717 /*********************************************************************** 718 * One time initialization, initialize the structure to store the times. 719 ***********************************************************************/ 720 public void initMain ( ) 721 //////////////////////////////////////////////////////////////////////// 722 { 723 // double tmp_time; 724 725 // minimum delay is 1ms 726 727 // minDelay = 0.001; 728 729 // fireQueue = new TreeQueue<FireEvent>(); 730 731 stop = false; 732 733 if ( info != null ) 734 { 735 localTime = new double [ info.numTasks ]; 736 } 737 738 // send initial input spikes from the sensory neuron to all the 739 // neurons in the network 740 741 /* 742 for(int i= 1; i< neurons.length; i++) 743 { 744 // 5Hz background input 745 tmp_time=-Math.log(Cnsran.ran2(idum))/5.0; 746 //sensory neuron send spikes to the other neurons 747 inputQueue.insertItem( new InputEvent(0,tmp_time,i,1e-10)); 748 } 749 inputQueue.show(); 750 */ 751 /* 752 tmp_time = (-Math.log(Cnsran.ran2(idum))/freq); 753 for(int i=0; i<info.endIndex.length; i++) 754 { 755 if(! (neurons[info.endIndex[i]] instanceof BKPoissonNeuron)) 756 { 757 //sensory neuron send spikes to the other neurons 758 fireQueue.insertItem( new FireEvent(info.endIndex[i]+base,tmp_time)); 759 } 760 } 761 */ 762 } 763 764 /*********************************************************************** 765 * process the event from fireQueue 766 * 767 * @param 768 * firstFire 769 ***********************************************************************/ 770 /* 771 public void fireProcess(FireEvent firstFire) 772 //////////////////////////////////////////////////////////////////////// 773 { 774 double tmp_firetime; 775 //note the sensory neuron will never fire 776 //p.println("fire: "+firstFire); 777 //if(firstFire.index!=0)inputQueue.show(); 778 779 if(firstFire.index>1000 && firstFire.index<1100) 780 { 781 System.out.println("fire: "+firstFire); 782 } 783 784 //System.out.println("fire: "+firstFire); 785 786 //first send out the spikes 787 for(int i=0 ; i < (neurons[firstFire.index].getAxon()).branches.length; 788 i++) 789 { 790 // if(firstFire.index==0) 791 // { 792 // System.out.println ( 793 // neurons [ firstFire.index ] 794 // .getAxon ( ).branches [ i ].synapses.length ); 795 // } 796 797 inputQueue.insertItem ( 798 new InputEvent ( 799 firstFire.time 800 + ( neurons [ firstFire.index ].getAxon ( ) ).branches [ i ] 801 .delay, 802 ( neurons [ firstFire.index ].getAxon ( ) ).branches [ i ], 803 firstFire.index ) ); 804 } 805 806 double timeOfNextEvent; 807 808 // neuron do fire 809 if( (timeOfNextEvent=neurons[firstFire.index].updateFire()) >=0.0 ) 810 { 811 812 tmp_firetime=firstFire.time+ timeOfNextEvent; 813 //neurons[firstFire.index].timeOfFire(); 814 neurons[firstFire.index].setTimeOfNextFire(tmp_firetime); 815 816 //insert this into the new firing queue; 817 fireQueue.insertItem(new FireEvent(firstFire.index, tmp_firetime)); 818 } 819 else 820 { 821 //if the neuron doesn't fire 822 neurons[firstFire.index].setTimeOfNextFire(-1); 823 } 824 fireQueue.deleteItem(firstFire); //delete this item 825 } 826 */ 827 828 /*********************************************************************** 829 * Process the event from fireQueue in parallel. 830 ***********************************************************************/ 831 public void pFireProcess ( final FireEvent firstFireEvent ) 832 throws jpvmException, Exception 833 //////////////////////////////////////////////////////////////////////// 834 { 835 final int adjustedNeuronIndex = firstFireEvent.index - base; 836 837 final Neuron neuron = neurons [ adjustedNeuronIndex ]; 838 839 /* 840 p.println("fire t:"+firstFire.time+" index:"+firstFire.index); 841 fireQueue.show(p); 842 inputQueue.show(p); 843 poissonQueue.show(p); 844 */ 845 846 double tmp_firetime; 847 848 // only neuron really fires 849 850 if ( neuron.realFire ( ) ) 851 { 852 // int host; 853 854 // if the neuron is recordable 855 856 if ( neuron.getRecord ( ) ) 857 { 858 // p.println(firstFire.index+" recorded"); 859 860 recordBuff.buff.add ( 861 new NetRecordSpike ( 862 firstFireEvent.time, 863 firstFireEvent.index ) ); 864 } 865 866/* 867 if ( firstFire.index != neurons.length + base - 1 868 && firstFire.index > 1000 869 && firstFire.index < 1100 ) //don't record special neurons 870 { 871 jpvmBuffer buff = new jpvmBuffer ( ); 872 873 buff.pack ( 874 new NetRecordSpike ( 875 localTime, 876 firstFire.time, 877 firstFire.index ) ); 878 879 info.jpvm.pvm_send ( 880 buff, 881 info.parent, 882 NetMessageTag.gatherFire ); 883 } 884*/ 885 // first send out the spikes 886 // int i=0; 887 // try 888 // { 889 // System.out.println ( 890 // "neuron:"+(firstFire.index-base)+" fire:"+firstFire.time); 891 892 long target = neuron.getTHost ( ); 893 894 for ( int i = 0; i < info.numTasks; i++ ) 895 { 896 if ( ( target & ( 1L << i ) ) != 0 ) // it has target at host i 897 { 898 if ( i == info.idIndex ) // localhost 899 { 900 final Integer 901 axonIndex = Integer.valueOf ( firstFireEvent.index ); 902 903 final Axon axon = axons.get ( axonIndex ); 904 905 final int axonBranchesLength = axon.branches.length; 906 907 for ( int iter = 0; iter < axonBranchesLength; iter++ ) 908 { 909 final Branch branch = axon.branches [ iter ]; 910 911 inputEventSlot.offer ( 912 new InputEvent ( 913 firstFireEvent.time + branch.delay, 914 branch, 915 firstFireEvent.index ) ); 916 } 917 } 918 else // remote host 919 { 920 spikeBuffers [ i ].buff.add ( 921 new NetMessage ( 922 firstFireEvent.time, 923 firstFireEvent.index ) ); 924 } 925 } 926 } 927 928 // } 929 // catch ( ArrayIndexOutOfBoundsException e ) 930 // { 931 // p.println ( "firstFire.index-base:"+firstFire.index+"-"+base 932 // +"="+(firstFire.index-base)+" uplimit"+neurons.length 933 // +" branch_length" 934 // +neurons[firstFire.index-base].getAxon().branches.length 935 // +" curr "+i + "synapse empty" 936 // + ( ( neurons [ firstFire.index - base ].getAxon ( ) ) 937 // .branches[i].synapses==null) 938 // + " syn:" 939 // + ( ( neurons [ firstFire.index - base ].getAxon ( ) ) 940 // .branches[i].synapses.length ) ); 941 // 942 // e.printStackTrace ( p ); 943 // } 944 } 945 946 double timeOfNextEvent; 947 948 // neuron do fire 949 950 if ( ( timeOfNextEvent = neuron.updateFire ( ) ) >= 0 ) 951 { 952 tmp_firetime = firstFireEvent.time + timeOfNextEvent; 953 954 // neurons[firstFire.index-base].timeOfFire(); 955 956 // insert this into the new firing queue; 957 958 fireQueue.insertItem ( 959 new FireEvent ( 960 firstFireEvent.index, 961 tmp_firetime ) ); 962 963 neuron.setTimeOfNextFire ( tmp_firetime ); 964 } 965 else 966 { 967 // if the neuron doesn't fire 968 969 neuron.setTimeOfNextFire ( -1 ); 970 } 971 972 // delete this item 973 974 fireQueue.deleteItem ( firstFireEvent ); 975 } 976 977 @SuppressWarnings("unused") 978 @Deprecated 979 public void pMainProcess ( 980 FireEvent firstFire, 981 double freq, 982 double weight, 983 Seed seed) 984 //////////////////////////////////////////////////////////////////////// 985 { 986 // 987 } 988 989 /*********************************************************************** 990 * process the event from (internal) inputQueue 991 * 992 * @param firstInput 993 ***********************************************************************/ 994 @Deprecated 995 public void inputProcess ( InputEvent firstInput ) 996 //////////////////////////////////////////////////////////////////////// 997 { 998 double tmp_firetime; 999 1000 //System.out.println("input: "+firstInput); 1001 1002 // first delete the false prediction 1003 1004 //System.out.println("input:"+firstInput); 1005 1006 for ( int i = 0; i < firstInput.branch.synapses.length ; i++) 1007 { 1008 // if ( firstInput.branch.synapses [ i ].to == 8300 ) 1009 // { 1010 // System.out.println("find trace"+firstInput+" 8300"); 1011 // } 1012 1013 // if last time predicts the neuron will fire in future 1014 1015 // TODO: requires cleanup 1016 1017 if ( neurons [ 1018 firstInput.branch.synapses [ i ].getTargetNeuronIndex ( ) ] 1019 .getTimeOfNextFire ( ) != -1 ) 1020 { 1021 // System.out.println ( 1022 // new FireEvent ( 1023 // firstInput.branch.synapses[i].to, 1024 // neurons [ firstInput.branch.synapses [ i ].to ] 1025 // .getTimeOfNextFire ( ) ) ); 1026 1027 fireQueue.deleteItem ( 1028 new FireEvent ( 1029 firstInput.branch.synapses [ i ].getTargetNeuronIndex ( ), 1030 neurons [ firstInput.branch.synapses [ i ].getTargetNeuronIndex ( ) ] 1031 .getTimeOfNextFire ( ) ) ); 1032 } 1033 1034 double timeOfNextEvent; 1035 1036 // neuron do fire 1037 1038 if ( ( timeOfNextEvent 1039 = neurons [ firstInput.branch.synapses [ i ] 1040 .getTargetNeuronIndex ( ) ].updateInput ( 1041 firstInput.time, 1042 firstInput.branch.synapses [ i ] ) ) >= 0.0 ) 1043 { 1044 tmp_firetime = firstInput.time + timeOfNextEvent; 1045 1046 //neurons[firstInput.branch.synapses[i].to].timeOfFire(); 1047 1048 neurons [ firstInput.branch.synapses [ i ] 1049 .getTargetNeuronIndex ( ) ] 1050 .setTimeOfNextFire ( tmp_firetime ); 1051 1052 //insert this into the new firing queue; 1053 1054 fireQueue.insertItem ( 1055 new FireEvent ( 1056 firstInput.branch.synapses [ i ].getTargetNeuronIndex ( ), 1057 tmp_firetime)); 1058 } 1059 else 1060 { 1061 // if the neuron doesn't fire 1062 1063 neurons [ firstInput.branch.synapses [ i ] 1064 .getTargetNeuronIndex ( ) ] 1065 .setTimeOfNextFire ( -1 ); 1066 } 1067 } 1068 1069 // delete this item 1070 1071 inputQueue.deleteItem ( firstInput ); 1072 } 1073 1074 /*********************************************************************** 1075 * poisson input process 1076 ***********************************************************************/ 1077 @Deprecated 1078 public void poissonProcess(PInputEvent poiInput) 1079 //////////////////////////////////////////////////////////////////////// 1080 { 1081 double tmp_firetime; 1082 1083 // if last time predicts the neuron will fire in future 1084 1085 if ( neurons [ poiInput.synapse.getTargetNeuronIndex ( ) ] 1086 .getTimeOfNextFire ( ) != -1 ) 1087 { 1088 // System.out.println ( 1089 // new FireEvent ( 1090 // firstInput.branch.synapses [ i ].to, 1091 // neurons [ firstInput.branch.synapses [ i ].to ] 1092 // .getTimeOfNextFire ( ) ) ); 1093 1094 fireQueue.deleteItem ( 1095 new FireEvent ( 1096 poiInput.synapse.getTargetNeuronIndex ( ), 1097 neurons [ poiInput.synapse.getTargetNeuronIndex ( ) ] 1098 .getTimeOfNextFire ( ) ) ); 1099 } 1100 1101 double timeOfNextEvent; 1102 1103 // neuron do fire 1104 1105 if ( ( timeOfNextEvent 1106 = neurons [ poiInput.synapse.getTargetNeuronIndex ( ) ] 1107 .updateInput ( 1108 poiInput.time, 1109 poiInput.synapse ) ) >=0.0 ) 1110 { 1111 tmp_firetime = poiInput.time + timeOfNextEvent; 1112 1113 // neurons[poiInput.synapse.to].timeOfFire(); 1114 1115 neurons [ poiInput.synapse.getTargetNeuronIndex ( ) ] 1116 .setTimeOfNextFire ( tmp_firetime ); 1117 1118 // insert this into the new firing queue; 1119 1120 fireQueue.insertItem ( 1121 new FireEvent ( 1122 poiInput.synapse.getTargetNeuronIndex ( ), 1123 tmp_firetime ) ); 1124 } 1125 else 1126 { 1127 // if the neuron doesn't fire 1128 1129 neurons [ poiInput.synapse.getTargetNeuronIndex ( ) ] 1130 .setTimeOfNextFire ( -1 ); 1131 } 1132 1133 poissonQueue.insertItem ( 1134 new PInputEvent ( 1135 poiInput.time + ( -Math.log ( Cnsran.ran2 ( seed ) ) 1136 / simulatorParser.backgroundFrequency ), 1137 poiInput.synapse, 1138 -1 ) ); 1139 1140 // delete this item 1141 1142 poissonQueue.deleteItem ( poiInput ); 1143 } 1144 1145 /*********************************************************************** 1146 * poisson input process (external input) in parallel 1147 ***********************************************************************/ 1148 public void pPoissonProcess ( PInputEvent poiInput ) 1149 //////////////////////////////////////////////////////////////////////// 1150 { 1151 final int targetNeuronIndex 1152 = poiInput.synapse.getTargetNeuronIndex ( ) - base; 1153 1154 final Neuron targetNeuron = neurons [ targetNeuronIndex ]; 1155 1156 // p.println("t:"+poiInput.time+" sourceID:"+poiInput.sourceId 1157 // +" id"+poiInput.synapse.to+" syn:"+poiInput.synapse); 1158 // p.flush(); 1159 // fireQueue.show(p); 1160 // inputQueue.show(p); 1161 // poissonQueue.show(p); 1162 1163 final double timeOfNextFire = targetNeuron.getTimeOfNextFire ( ); 1164 1165 if ( timeOfNextFire != -1 ) 1166 { 1167 // if last time predicts the neuron will fire in future 1168 1169 fireQueue.deleteItem ( 1170 new FireEvent ( 1171 poiInput.synapse.getTargetNeuronIndex ( ), 1172 targetNeuron.getTimeOfNextFire ( ) ) ); 1173 } 1174 1175 final double 1176 timeOfNextEvent = targetNeuron.updateInput ( 1177 poiInput.time, 1178 poiInput.synapse ); 1179 1180 // neuron do fire 1181 1182 if ( timeOfNextEvent >= 0.0 ) 1183 { 1184 // p.println("neuron fire"); 1185 // p.flush(); 1186 1187 final double 1188 tmp_firetime = poiInput.time + timeOfNextEvent; 1189 1190 //neurons[poiInput.synapse.to-base].timeOfFire(); 1191 1192 // insert this into the new firing queue 1193 1194 fireEventSlot.offer ( 1195 new FireEvent ( 1196 poiInput.synapse.getTargetNeuronIndex ( ), 1197 tmp_firetime ) ); 1198 1199 targetNeuron.setTimeOfNextFire ( tmp_firetime ); 1200 1201 // p.println("neuron time called"); 1202 // p.flush(); 1203 } 1204 else 1205 { 1206 // p.println("neuron doesn't fire"); 1207 // p.flush(); 1208 1209 // if the neuron doesn't fire 1210 1211 targetNeuron.setTimeOfNextFire ( -1 ); 1212 } 1213 1214 // p.println("input is updated"); 1215 // p.flush(); 1216 1217 if ( poiInput.sourceId == -1 ) 1218 { 1219 poissonQueue.insertItem ( 1220 new PInputEvent ( 1221 poiInput.time + ( -Math.log ( Cnsran.ran2 ( seed ) ) 1222 / simulatorParser.backgroundFrequency ), 1223 poiInput.synapse, 1224 -1 ) ); 1225 } 1226 else 1227 { 1228 final SubExp 1229 subExp = experiment.subExp [ subExpId ]; 1230 1231 final Stimulus 1232 stimulus = subExp.stimuli [ poiInput.sourceId ]; 1233 1234 final double timeOfNext 1235 = stimulus.getNextTime ( poiInput.time ); 1236 1237 if ( timeOfNext >= 0 ) 1238 { 1239 //p.println("t:"+timeOfNext+" sourceID:"+poiInput.sourceId 1240 //+" id"+poiInput.synapse.to); 1241 1242 poissonQueue.insertItem ( 1243 new PInputEvent ( 1244 timeOfNext, 1245 poiInput.synapse, 1246 poiInput.sourceId ) ); 1247 } 1248 } 1249 1250 // delete this item 1251 1252 poissonQueue.deleteItem ( poiInput ); 1253 } 1254 1255 /*********************************************************************** 1256 * Process the event from inputQueue in parallel. 1257 ***********************************************************************/ 1258 public void pInputProcess ( final InputEvent firstInputEvent ) 1259 //////////////////////////////////////////////////////////////////////// 1260 { 1261 // p.println("INPUT"); 1262 // fireQueue.show(p); 1263 // inputQueue.show(p); 1264 // poissonQueue.show(p); 1265 1266 for ( final Synapse synapse : firstInputEvent.branch.synapses ) 1267 { 1268 // if(firstInput.branch.synapses[i].to==8300) 1269 // p.println("find trace"+firstInput+" 8300"); 1270 1271 // TODO: rename to adjustedTargetNeuronIndex 1272 1273 final int 1274 targetNeuronIndex = synapse.getTargetNeuronIndex ( ) - base; 1275 1276 final Neuron targetNeuron = neurons [ targetNeuronIndex ]; 1277 1278 // if last time predicts the neuron will fire in future 1279 1280 final double timeOfNextFire = targetNeuron.getTimeOfNextFire ( ); 1281 1282 if ( timeOfNextFire != -1 ) 1283 { 1284 fireQueue.deleteItem ( 1285 new FireEvent ( 1286 synapse.getTargetNeuronIndex ( ), 1287 timeOfNextFire ) ); 1288 } 1289 1290 final double timeOfNextEvent = targetNeuron.updateInput ( 1291 firstInputEvent.time, 1292 synapse ); 1293 1294 // neuron do fire 1295 1296 if ( timeOfNextEvent >= 0.0 ) 1297 { 1298 final double 1299 tmp_firetime = firstInputEvent.time + timeOfNextEvent; 1300 1301 // neurons[firstInput.branch.synapses[i].to-base].timeOfFire(); 1302 1303 // insert this into the new firing queue; 1304 1305 fireQueue.insertItem ( 1306 new FireEvent ( 1307 synapse.getTargetNeuronIndex ( ), 1308 tmp_firetime ) ); 1309 1310 targetNeuron.setTimeOfNextFire ( tmp_firetime ); 1311 } 1312 else 1313 { 1314 // if the neuron doesn't fire 1315 1316 targetNeuron.setTimeOfNextFire ( -1 ); 1317 } 1318 } 1319 1320 // delete this item 1321 1322 inputQueue.deleteItem ( firstInputEvent ); 1323 } 1324 1325/* 1326 public void testRun() 1327 //////////////////////////////////////////////////////////////////////// 1328 { 1329 FireEvent firstFire; 1330 InputEvent firstInput; 1331 PInputEvent poiInput; 1332 double minTime; 1333 double fireTime, inputTime, pInputTime; 1334// System.out.println("before running..."); 1335 1336// inputQueue.show(); 1337 1338 while(!stop) 1339 { 1340 // take out the first fire element 1341 firstFire = fireQueue.firstItem(); 1342 // take out the first input element 1343 firstInput = inputQueue.firstItem(); 1344 // take out the first poisson input element 1345 poiInput = poissonQueue.firstItem(); 1346 1347// System.out.println("running..."); 1348 1349 if(firstFire != null) 1350 { 1351 fireTime=firstFire.time; 1352 } 1353 else 1354 { 1355 fireTime=Double.MAX_VALUE; 1356 } 1357 1358 if(firstInput != null) 1359 { 1360 inputTime=firstInput.time; 1361 } 1362 else 1363 { 1364 inputTime=Double.MAX_VALUE; 1365 } 1366 1367 if(poiInput != null) 1368 { 1369 pInputTime=poiInput.time; 1370 } 1371 else 1372 { 1373 pInputTime=Double.MAX_VALUE; 1374 } 1375 1376 minTime = ( fireTime < inputTime? fireTime: inputTime); 1377 minTime = (minTime < pInputTime? minTime: pInputTime); 1378 1379 if( firstFire != null && minTime == firstFire.time) //fire event 1380 { 1381// System.out.println("fire.."+firstFire); 1382 fireProcess(firstFire); 1383 1384 } 1385 // input event 1386 else if ( firstInput !=null && minTime == firstInput.time) 1387 { 1388 // System.out.println("input.."); 1389 inputProcess(firstInput); 1390 } 1391 // poissoninput event 1392 else if ( poiInput !=null && minTime == poiInput.time) 1393 { 1394// System.out.println("background: "+poiInput.synapse.to); 1395 poissonProcess(poiInput); 1396 } 1397 } 1398 } 1399*/ 1400 1401 //////////////////////////////////////////////////////////////////////// 1402 // private methods 1403 //////////////////////////////////////////////////////////////////////// 1404 1405 private void clearModulationFactors ( ) 1406 //////////////////////////////////////////////////////////////////////// 1407 { 1408 if ( modulatedSynapseSeq == null ) 1409 { 1410 return; 1411 } 1412 1413 final int size = modulatedSynapseSeq.size ( ); 1414 1415 for ( int i = 0; i < size; i++ ) 1416 { 1417 final ModulatedSynapse 1418 modulatedSynapse = modulatedSynapseSeq.get ( i ); 1419 1420 modulatedSynapse.clearModulationFactors ( ); 1421 } 1422 } 1423 1424 //////////////////////////////////////////////////////////////////////// 1425 //////////////////////////////////////////////////////////////////////// 1426 }