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.*; 010 011 import cnslab.cnsmath.*; 012 import edu.jhu.mb.ernst.model.Synapse; 013 014 /*********************************************************************** 015 * Sync neuron (fake neuron, id is the last neuron index), 016 * used to synchronize between NetHosts, used to send half minimum 017 * synaptic delay time ticks, send buffered spikes 018 * 019 * @version 020 * $Date: 2012-08-04 13:43:22 -0500 (Sat, 04 Aug 2012) $ 021 * $Rev: 104 $ 022 * $Author: croft $ 023 * @author 024 * Yi Dong 025 * @author 026 * David Wallace Croft 027 ***********************************************************************/ 028 public final class SYNNeuron 029 implements Neuron, Serializable 030 //////////////////////////////////////////////////////////////////////// 031 //////////////////////////////////////////////////////////////////////// 032 { 033 034 private static final Class<SYNNeuron> 035 CLASS = SYNNeuron.class; 036 037 private static final Logger 038 LOGGER = LoggerFactory.getLogger ( CLASS ); 039 040 private static final long serialVersionUID = 0L; 041 042 // 043 044 /** background frequency */ 045 private Network network; 046 047 public double tick; 048 049// Axon axon; 050 051 //////////////////////////////////////////////////////////////////////// 052 //////////////////////////////////////////////////////////////////////// 053 054 public SYNNeuron ( final Network network ) 055 //////////////////////////////////////////////////////////////////////// 056 { 057 this.network = network; 058 059 tick = network.minSynapticDelay / 2.0; 060 } 061 062 //////////////////////////////////////////////////////////////////////// 063 //////////////////////////////////////////////////////////////////////// 064 065 @Override 066 public void setTimeOfNextFire ( final double nextFire ) 067 //////////////////////////////////////////////////////////////////////// 068 { 069 if ( network.info.jpvm == null ) 070 { 071 // TODO: Hack for unit testing without distributed computing 072 // I am not sure if this is correct. -- Croft 073 074 final double currTime = nextFire - tick; 075 076 if ( currTime >= network.endOfTrial ) 077 { 078 int trial = network.trialId; 079 080 int expid = network.subExpId; 081 082 processData ( expid, trial ); 083 084 network.p.println ( "trial done" ); 085 086 network.trialDone = true; 087 088 network.spikeState = true; 089 090 for ( int iter = 0; iter < network.info.numTasks; iter++ ) 091 { 092 network.received [ iter ] = 1; 093 } 094 095 network.rootTime = 0.0; 096 097 network.clearQueues ( ); 098 099 network.countTrial++; 100 101 // double hack 102 103 network.stop = true; 104 } 105 106 return; 107 } 108 109 // if synNeuron at currTime could be processed, it was guaranteed that 110 // the spikes sent by synNeuron at currTime-tick are received. 111 112// network.p.print("sync T"+":"+network.rootTime+" "); 113// network.p.print("\n"); 114 115 try 116 { 117 // send current time to the root; 118 119 final double currTime = nextFire - tick; 120 121 jpvmBuffer buff = new jpvmBuffer ( ); 122 123 buff.pack ( currTime ); //pack the sysTime 124 125 buff.pack ( network.info.idIndex ); //pack the hostId 126 127 // tell the root the current time 128 129 network.info.jpvm.pvm_send ( 130 buff, 131 network.info.parentJpvmTaskId, 132 NetMessageTag.sendTick ); 133 134 int countN = 0; 135 136 for ( int k = 0; 137 k < network.experiment.recorder.intraEle.size ( ); k++ ) 138 { 139 for ( int m = 0; 140 m < network.experiment.recorder.intraEle.get ( k ).size ( ); m++ ) 141 { 142 final Neuron tmpN = network.neurons [ 143 network.intraRecBuffers.neurons [ k ] - network.base ]; 144 145 final LinkedList<Double> curr = new LinkedList<Double> ( ); 146 147 final double [ ] allCurr = tmpN.getCurr ( currTime ); 148 149 for( int j = 0; 150 j < network.experiment.recorder.currChannel.get ( k ).size ( ); 151 j++ ) 152 { 153 curr.add ( allCurr [ 154 network.experiment.recorder.currChannel.get ( k ).get ( j ) ] ); 155 } 156 157 network.intraRecBuffers.buff.get ( countN ).add ( 158 new IntraInfo ( tmpN.getMemV ( currTime ), curr ) ); 159 160 countN++; 161 } 162 } 163 164 // network.p.print(network.intraBuff); 165 166 if ( currTime + network.minSynapticDelay < network.endOfTrial ) 167 { 168// network.p.println("sent at "+currTime); 169 170 for ( int i = 0; i < network.info.numTasks; i++ ) 171 { 172 if ( i != network.info.idIndex ) //not to him self 173 { 174 buff = new jpvmBuffer(); 175 176 buff.pack(network.info.idIndex); //source id; 177 178 buff.pack(network.countTrial);// trial id info 179 180// buff.pack(network.rootTime); // local root time; 181// buff.pack(currTime); // local root time; 182 183 buff.pack(network.spikeBuffers[i]); //pack the spike buffer 184 185 // send the spikes to the target host 186 187 network.info.jpvm.pvm_send ( 188 buff, 189 network.info.tids [ i ], 190 NetMessageTag.sendSpike ); 191 192 // clear buffer 193 194 network.spikeBuffers [ i ].buff.clear ( ); 195 } 196 } 197 } 198 else 199 { 200 for ( int iter = 0; iter < network.info.numTasks; iter++ ) 201 { 202 if ( iter != network.info.idIndex ) 203 { 204 ( network.received [ iter ] )++; 205 } 206 } 207 208 network.spikeState = true; 209 } 210 211 if ( currTime >= network.endOfTrial ) 212 { 213 // network.p.println("trial done ini"+minTime); 214 215 jpvmBuffer buf = new jpvmBuffer(); 216 217 int trial = network.trialId; 218 219 int expid = network.subExpId; 220 221// network.p.print("E"+network.subExpId+" T"+trial); 222 223 buf.pack(trial); //trial id and subexp id 224 225 buf.pack(expid); 226 227 //buf.pack(network.info.idIndex); 228 229 // don't send it, process it first 230 // buf.pack(network.recordBuff); 231 232 processData ( expid, trial ); 233 234 // send the intracellular info back to root 235 236 buf.pack ( network.intraRecBuffers ); 237 238 //send root to say the trial is done 239 240 // network.info.jpvm.pvm_send( 241 // buf,network.info.parent,NetMessageTag.trialDone); 242 243 network.p.println ( "trial done" ); 244 245 //break; 246 247 network.trialDone = true; 248 249 //added; 250 251 network.spikeState = true; 252 253 for ( int iter = 0; iter < network.info.numTasks; iter++ ) 254 { 255 /* 256 while(!network.received[iter].empty()) 257 { 258 network.received[iter].pop(); 259 } 260 */ 261 262 // leave mark here 263 264 network.received [ iter ] = 1; 265 } 266 267 //added over; 268 269 //initialization 270 271 network.rootTime = 0.0; 272 273 network.clearQueues ( ); 274 275 network.countTrial++; 276 277 //network.init(); 278 279 network.info.jpvm.pvm_send ( 280 buf, 281 network.info.tids [ network.info.idIndex ], 282 NetMessageTag.trialDone ); 283 284 buf = new jpvmBuffer ( ); 285 286 // network.p.println( 287 // "e:"+expid+"t:"+trial+" host:"+network.info.parent.getHost()); 288 289 network.info.jpvm.pvm_barrier ( 290 network.info.parentJpvmTaskId.getHost ( ), 291 expid * network.experiment.subExp.length + trial, 292 network.info.numTasks ); 293 294 // network.p.println("ov_e:"+expid+"t:"+trial); 295 // network.p.flush(); 296 297 network.info.jpvm.pvm_send ( 298 buf, 299 network.info.parentJpvmTaskId, 300 NetMessageTag.trialDone ); 301 } 302 } 303 catch ( final jpvmException ex ) 304 { 305 ex.printStackTrace(network.p); 306 307 network.p.println ( 308 "Error - Sync failed to send message to the root " 309 +network.rootTime ); 310 311 network.p.println ( ex ); 312 } 313 catch ( final Exception e ) 314 { 315 e.printStackTrace ( ); 316 } 317 } 318 319 /** 320 * @see cnslab.cnsnetwork.Neuron#timeOfFire() timeOfFire 321 */ 322// TODO: Why does @Override not work here? Interface changed? 323// @Override 324 public double timeOfFire(double curr) 325 //////////////////////////////////////////////////////////////////////// 326 { 327 return tick; 328 } 329 330 /** 331 * @see cnslab.cnsnetwork.Neuron#updateFire() updateFire 332 */ 333 @Override 334 public double updateFire() 335 //////////////////////////////////////////////////////////////////////// 336 { 337// throw new RuntimeException("sensory neuron won't update fire"); 338 return tick; 339// return true; 340 } 341 342 /** 343 * @see cnslab.cnsnetwork.Neuron#updateInput( 344 * cnslab.cnsnetwork.InputEvent) updateInput 345 */ 346 @Override 347 public double updateInput(double time, Synapse input) 348 //////////////////////////////////////////////////////////////////////// 349 { 350 throw new RuntimeException("sensory neuron won't recieve inputs"); 351 } 352 353 /** 354 * @see cnslab.cnsnetwork.Neuron#getTimeOfNextFire() getTimeOfNextFire 355 */ 356 @Override 357 public double getTimeOfNextFire() 358 //////////////////////////////////////////////////////////////////////// 359 { 360 return -1; 361 } 362 363/* 364 public Axon getAxon() 365 { 366 return axon; 367 } 368 */ 369 370 /** 371 * @see java.lang.Object#toString() toString 372 */ 373 @Override 374 public String toString() 375 //////////////////////////////////////////////////////////////////////// 376 { 377 String tmp="Synchroizing clock neuron\n"; 378 return tmp; 379 } // END: toString 380 381 /** 382 * @see cnslab.cnsnetwork.Neuron#isSensory() isSensory 383 */ 384 @Override 385 public boolean isSensory() 386 //////////////////////////////////////////////////////////////////////// 387 { 388 return true; 389 } 390 391 /** 392 * {@inheritDoc} 393 * @see Neuron#init(int,int,Seed,Network,int) 394 */ 395 @Override 396 public void init(int expid, int trialid, Seed idum, Network net, int id) 397 //////////////////////////////////////////////////////////////////////// 398 { 399 throw new RuntimeException("sensory neuron won't need init"); 400 } 401 402 /** 403 * record the neuron 404 * @return boolean whether it should be recorded 405 */ 406 @Override 407 public boolean getRecord() 408 //////////////////////////////////////////////////////////////////////// 409 { 410 return false; //fake neuron can't be recorded 411 } 412 413 /** 414 *set the neuron record or not. 415 */ 416 @Override 417 public void setRecord(boolean record) 418 //////////////////////////////////////////////////////////////////////// 419 { 420 //nothing is done 421 } 422 423 /** 424 * @return neuron's current memory voltage 425 */ 426 @Override 427 public double getMemV(double currTime) 428 //////////////////////////////////////////////////////////////////////// 429 { 430 throw new RuntimeException("no memV for sensory neuron"); 431 } 432 433 /** 434 * 435 * @return neuron's current currents of all the channels 436 */ 437 @Override 438 public double [] getCurr(double currTime) 439 //////////////////////////////////////////////////////////////////////// 440 { 441 throw new RuntimeException("no curr for sensory neuron"); 442 } 443 444 //////////////////////////////////////////////////////////////////////// 445 //////////////////////////////////////////////////////////////////////// 446 447 private void processData ( 448 final int expid, 449 final int trial ) 450 //////////////////////////////////////////////////////////////////////// 451 { 452 //RecordBuffer spikes = Network.recordBuff; 453 454 final Iterator<NetRecordSpike> 455 iter_spike = network.recordBuff.buff.iterator(); 456 457 while(iter_spike.hasNext()) 458 { 459 NetRecordSpike spike = iter_spike.next(); 460 461 //single unit processing 462 463 //if neuron is in single unit recorder 464 465 if(network.experiment.recorder.singleUnit.contains(spike.from)) 466 { 467 LinkedList<Double> tmp 468 = network.recorderData.receiver.get ( 469 "E" + expid + "T" + trial + "N" + spike.from ); 470 471 if ( tmp == null ) 472 { 473 network.recorderData.receiver.put ( 474 "E" + expid + "T" + trial + "N" + spike.from, 475 tmp = ( new LinkedList<Double> ( ) ) ); 476 } 477 478 //put received info into memory 479 // if ( spike.time !=0.0 ) tmp.add(spike.time); 480 481 //put received info into memory 482 tmp.add ( spike.time ); 483 484 // System.out.println( 485 // "fire: time:"+spike.time+ " index:"+spike.from); 486 } 487 488 // multiple unit processing 489 490 final int 491 multiUnitSize = network.experiment.recorder.multiUnit.size ( ); 492 493 for ( int mID = 0; mID < multiUnitSize; mID++ ) 494 { 495 final ArrayList<Integer> neuronIndexList 496 = network.experiment.recorder.multiUnit.get ( mID ); 497 498 if ( neuronIndexList.contains ( spike.from ) ) 499 { 500 // LOGGER.trace ( 501 // "Recording MultiUnit spike from {}", 502 // spike.from ); 503 504 final int binIndex = ( int ) 505 ( spike.time / network.experiment.recorder.timeBinSize ); 506 507 // LOGGER.trace ( "binIndex {}", binIndex ); 508 509 final String key = "E" + expid + "N" + mID + "B" + binIndex; 510 511 Integer tmpInt = network.recorderData.multiCounter.get ( key ); 512 513 if ( tmpInt == null ) 514 { 515 tmpInt = new Integer ( 0 ); 516 } 517 518 tmpInt = tmpInt + 1; 519 520 network.recorderData.multiCounter.put ( 521 key, 522 tmpInt ); 523 524 // LOGGER.trace ( "key {} tmpInt {}", key, tmpInt ); 525 526 final String keyAll 527 = "E" + expid + "T" + trial + "N" + mID + "B" + binIndex; 528 529 Integer tmpIntAll 530 = network.recorderData.multiCounterAll.get ( keyAll ); 531 532 if ( tmpIntAll == null ) 533 { 534 tmpIntAll = new Integer ( 0 ); 535 } 536 537 tmpIntAll = tmpIntAll + 1; 538 539 network.recorderData.multiCounterAll.put ( 540 keyAll, 541 tmpIntAll ); 542 } 543 } 544 545 // field processing 546 for ( int fID = 0; 547 fID < network.experiment.recorder.fieldEle.size ( ); fID++ ) 548 { 549 if ( network.simulatorParser.layerStructure.celltype [ 550 spike.from - network.base ].matches ( "^" 551 + network.experiment.recorder.fieldEle.get ( fID ).getPrefix ( ) 552 + ",.*," 553 + network.experiment.recorder.fieldEle.get ( fID ).getSuffix ( ) 554 + "$" ) ) 555 { 556// int [] xy = network.pas.ls.celllayer_cordinate( 557// spike.from,network.exp.rec.fieldEle.get(fID).getPrefix(), 558// network.exp.rec.fieldEle.get(fID).getSuffix()); 559 560 final int binIndex = ( int ) 561 ( spike.time / network.experiment.recorder.fieldTimeBinSize ); 562 563 Integer tmpInt = network.recorderData.fieldCounter.get ( 564 "E" + expid + "," 565 + network.simulatorParser.layerStructure.celltype [ 566 spike.from - network.base ] 567 + "," + "B" + binIndex ); 568 569 if ( tmpInt == null ) 570 { 571 network.recorderData.fieldCounter.put ( 572 "E"+expid+"," 573 + network.simulatorParser.layerStructure.celltype [ 574 spike.from-network.base ] 575 + "," + "B" + binIndex, 576 tmpInt = ( new Integer ( 0 ) ) ); 577 } 578 579 tmpInt = tmpInt + 1; 580 581 network.recorderData.fieldCounter.put ( 582 "E" + expid + "," 583 + network.simulatorParser.layerStructure.celltype [ 584 spike.from-network.base ] 585 + "," + "B" + binIndex, 586 tmpInt); 587 } 588 } 589 590 //vector processing 591 592 for ( int vID = 0; 593 vID < network.experiment.recorder.vectorUnit.size ( ); vID++ ) 594 { 595 for ( int cID = 0; 596 cID 597 < network.experiment.recorder.vectorUnit.get ( vID ).coms.size ( ); 598 cID++) 599 { 600 if ( network.simulatorParser.layerStructure.celltype [ 601 spike.from-network.base ].matches ( 602 "^" + network.experiment.recorder.vectorUnit.get ( vID ) 603 .coms.get ( cID ).layer.getPrefix ( ) 604 + ",.*," + network.experiment.recorder.vectorUnit.get ( vID ) 605 .coms.get ( cID ).layer.getSuffix ( ) + "$" ) ) 606 { 607 // int [] xy = network.pas.ls.celllayer_cordinate( 608 // spike.from,network.exp.rec.vectorUnit.get(vID) 609 // .coms.get(cID).layer.getPrefix(), 610 // network.exp.rec.vectorUnit.get(vID) 611 // .coms.get(cID).layer.getSuffix()); 612 613 int id_begin=0; 614 615 int id_mid=0; 616 617 int id_end=0; 618 619 id_begin = network.simulatorParser.layerStructure.celltype[ 620 spike.from-network.base].indexOf(',',0); 621 622 id_mid = network.simulatorParser.layerStructure.celltype[ 623 spike.from-network.base].indexOf(',',id_begin+1); 624 625 id_end = network.simulatorParser.layerStructure.celltype[ 626 spike.from-network.base].indexOf(',',id_mid+1); 627 628 String xy_x = network.simulatorParser.layerStructure.celltype[ 629 spike.from-network.base].substring(id_begin+1,id_mid); 630 631 String xy_y = network.simulatorParser.layerStructure.celltype[ 632 spike.from-network.base].substring(id_mid+1,id_end); 633 634 final int binIndex = ( int ) 635 ( spike.time / network.experiment.recorder.vectorTimeBinSize ); 636 637 Double tmpDX = network.recorderData.vectorCounterX.get ( 638 "E"+expid+"V"+vID+"B"+binIndex+"C"+xy_x+","+xy_y ); 639 640 Double tmpDY = network.recorderData.vectorCounterY.get ( 641 "E"+expid+"V"+vID+"B"+binIndex+"C"+xy_x+","+xy_y ); 642 643 if ( tmpDX == null ) 644 { 645 network.recorderData.vectorCounterX.put ( 646 "E"+expid+"V"+vID+"B"+binIndex+"C"+xy_x+","+xy_y, 647 tmpDX=(new Double(0.0))); 648 649 network.recorderData.vectorCounterY.put ( 650 "E"+expid+"V"+vID+"B"+binIndex+"C"+xy_x+","+xy_y, 651 tmpDY=(new Double(0.0))); 652 } 653 654 tmpDX = tmpDX + Math.cos ( Math.PI / 180.0 655 * ( double ) network.experiment.recorder.vectorUnit.get ( vID ) 656 .coms.get ( cID ).orientation ); 657 658 tmpDY = tmpDY + Math.sin ( Math.PI / 180.0 659 * ( double ) network.experiment.recorder.vectorUnit.get ( vID ) 660 .coms.get ( cID ).orientation ); 661 662 network.recorderData.vectorCounterX.put ( 663 "E"+expid+"V"+vID+"B"+binIndex+"C"+xy_x+","+xy_y, 664 tmpDX ); 665 666 network.recorderData.vectorCounterY.put ( 667 "E"+expid+"V"+vID+"B"+binIndex+"C"+xy_x+","+xy_y, 668 tmpDY ); 669 } 670 } 671 } 672 } 673 } 674 675 /** 676 * {@inheritDoc} 677 * @see Neuron#getTHost() 678 */ 679 @Override 680 public long getTHost() 681 //////////////////////////////////////////////////////////////////////// 682 { 683 return 0; 684 } 685 686 /** 687 * set the target host id //0 means none , 1 means yes 688 */ 689 @Override 690 public void setTHost(long id) 691 //////////////////////////////////////////////////////////////////////// 692 { 693 694 } 695 696 /** 697 * {@inheritDoc} 698 * @see Neuron#realFire() 699 */ 700 @Override 701 public boolean realFire() 702 //////////////////////////////////////////////////////////////////////// 703 { 704 return true; 705 } 706 707 //////////////////////////////////////////////////////////////////////// 708 //////////////////////////////////////////////////////////////////////// 709 }