001 package cnslab.cnsnetwork; 002 003 import java.io.Serializable; 004 import java.util.ArrayList; 005 006 import org.slf4j.Logger; 007 import org.slf4j.LoggerFactory; 008 009 /*********************************************************************** 010 * The class used to record neuron activities. 011 * 012 * @version 013 * $Date: 2012-08-04 13:43:22 -0500 (Sat, 04 Aug 2012) $ 014 * $Rev: 104 $ 015 * $Author: croft $ 016 * @author 017 * Yi Dong 018 * @author 019 * David Wallace Croft 020 ***********************************************************************/ 021 public final class Recorder 022 implements Serializable, Transmissible 023 //////////////////////////////////////////////////////////////////////// 024 //////////////////////////////////////////////////////////////////////// 025 { 026 027 private static final Class<Recorder> 028 CLASS = Recorder.class; 029 030 private static final Logger 031 LOGGER = LoggerFactory.getLogger ( CLASS ); 032 033 private static final long serialVersionUID = 0L; 034 035 // 036 037 public String outputFile; 038 039 public boolean plot; 040 041 public SimulatorParser simulatorParser; 042 043 //type 1 single unit electrode. 044 /** 045 * Single unit array, stored the array of recorded index of neurons 046 */ 047 public ArrayList<Integer> singleUnit; 048 049 /** 050 * Single unit name array 051 */ 052 public ArrayList<String> suNames; 053 054 //type 2 multiunit electrode. 055 /** 056 * Multi unit array, stored the array of recorded index of neurons 057 */ 058 public ArrayList<ArrayList<Integer>> multiUnit; 059 060 /** 061 * Multi unit array, stored the array of recorded neuron names 062 */ 063 public ArrayList<ArrayList<String>> neuronNames; 064 065 /** 066 * Multi unit recorder names 067 */ 068 public ArrayList<String> multiNames; 069 070 /** 071 * time resolution 072 */ 073 public double timeBinSize; 074 075 //type 3a field electrode. 076 public ArrayList<Layer> fieldEle; 077 078 public ArrayList<String> fieldNames; 079 080 public double fieldTimeBinSize; 081 082 //type 3b vector electrode. 083 public ArrayList<VComponents> vectorUnit; 084 085 public ArrayList<String> vectorNames; 086 087 public double vectorTimeBinSize; 088 089 //type 4 curr and memV intracellular electrode. 090 /** 091 * Intracelluar electrodes, pool the inner arraylist of neurons info 092 * together 093 */ 094 public ArrayList<ArrayList<Integer>> intraEle; 095 096 /** 097 * Intracelluar electrodes, the current channels that needs to be 098 * recorded. 099 */ 100 public ArrayList<ArrayList<Integer>> currChannel; 101 102 public ArrayList<String> intraNames; 103 104 public double intraTimeBinSize; 105 106 //////////////////////////////////////////////////////////////////////// 107 // constructor methods 108 //////////////////////////////////////////////////////////////////////// 109 110 public Recorder ( 111 final SimulatorParser simulatorParser, 112 final boolean plot ) 113 //////////////////////////////////////////////////////////////////////// 114 { 115 this.simulatorParser = simulatorParser; 116 117 this.plot = plot; 118 119 singleUnit = new ArrayList<Integer> ( ); 120 121 suNames = new ArrayList<String> ( ); 122 123 multiUnit = new ArrayList< ArrayList<Integer> >(); 124 neuronNames = new ArrayList< ArrayList<String> >(); 125 multiNames = new ArrayList< String >(); 126 127 fieldEle = new ArrayList< Layer >(); 128 fieldNames = new ArrayList< String >(); 129 130 vectorUnit = new ArrayList< VComponents >(); 131 vectorNames = new ArrayList< String > (); 132 133 intraEle = new ArrayList< ArrayList<Integer> >(); 134 currChannel = new ArrayList< ArrayList<Integer> >(); 135 intraNames = new ArrayList< String >(); 136 outputFile=""; 137 } 138 139 //////////////////////////////////////////////////////////////////////// 140 //////////////////////////////////////////////////////////////////////// 141 142 public int intraIndex ( final int neuron ) 143 //////////////////////////////////////////////////////////////////////// 144 { 145 for ( int i = 0; i < intraEle.size ( ); i++ ) 146 { 147 for ( int j = 0; j < intraEle.get ( i ).size ( ); j++ ) 148 { 149 if ( intraEle.get ( i ).get ( j ).intValue ( ) == neuron ) 150 { 151 return i; 152 } 153 } 154 } 155 156 throw new RuntimeException ( "recorded wrong cell" ); 157 } 158 159 public int [ ] intraNeurons ( ) 160 //////////////////////////////////////////////////////////////////////// 161 { 162 ArrayList<Integer> allNeurons = new ArrayList<Integer>(); 163 164 for(int i =0 ; i< intraEle.size(); i++) 165 { 166 allNeurons.addAll(intraEle.get(i)); 167 } 168 169 int [] tmp = new int[allNeurons.size()]; 170 171 int i=0; 172 173 for( int x : allNeurons) 174 { 175 tmp[i] = x; 176 177 i++; 178 } 179 180 return tmp; 181 } 182 183 public VComponents addComs() 184 //////////////////////////////////////////////////////////////////////// 185 { 186 VComponents vs; 187 vectorUnit.add(vs=new VComponents()); 188 return vs; 189 } 190 191 /*********************************************************************** 192 * Set the layer of neurons which needs to be recorded. 193 * 194 * @param layer 195 ***********************************************************************/ 196 public void setLayerNeurons(Layer layer, int hostId) 197 //////////////////////////////////////////////////////////////////////// 198 { 199 int xTotal=0; 200 int yTotal=0; 201 int xstep=0; 202 int ystep=0; 203 204 int xMul = layer.getMultiplierX(); 205 int yMul = layer.getMultiplierY(); 206 207 if(xMul < 0 ) 208 { 209 xTotal=simulatorParser.xEdgeLength; 210 xstep=-xMul; 211 } 212 else 213 { 214 xTotal=simulatorParser.xEdgeLength*xMul; 215 xstep=1; 216 } 217 if(yMul < 0 ) 218 { 219 yTotal=simulatorParser.yEdgeLength; 220 ystep=-yMul; 221 } 222 else 223 { 224 yTotal=simulatorParser.yEdgeLength*yMul; 225 ystep=1; 226 } 227 228 for( int x = 0; x< xTotal; x+=xstep) 229 { 230 for(int y = 0; y< yTotal; y+=ystep) 231 { 232 // String neu 233 // = layer.getPrefix()+","+x+","+y+","+layer.getSuffix(); 234 235 int id = simulatorParser.layerStructure.cellmap_slow ( 236 layer.getPrefix(), 237 layer.getSuffix(),x, 238 y); 239 240 if(id!=-1) 241 { 242 if ( FunUtil.hostId ( 243 simulatorParser.layerStructure.nodeEndIndices, id ) 244 == hostId ) 245 { 246 simulatorParser.layerStructure.neurons [ 247 id - simulatorParser.layerStructure.base ] 248 .setRecord ( true ); 249 } 250 } 251 else 252 { 253 // throw new RuntimeException("not in the grid"); 254 } 255 } 256 } 257 } 258 259 /*********************************************************************** 260 * Set the layer of neurons which needs to be recorded. 261 ***********************************************************************/ 262 public void setLayerNeurons ( final Layer layer ) 263 //////////////////////////////////////////////////////////////////////// 264 { 265 int xTotal=0; 266 int yTotal=0; 267 int xstep=0; 268 int ystep=0; 269 270 int xMul = layer.getMultiplierX(); 271 int yMul = layer.getMultiplierY(); 272 273 if(xMul < 0 ) 274 { 275 xTotal=simulatorParser.xEdgeLength; 276 xstep=-xMul; 277 } 278 else 279 { 280 xTotal=simulatorParser.xEdgeLength*xMul; 281 xstep=1; 282 } 283 if(yMul < 0 ) 284 { 285 yTotal=simulatorParser.yEdgeLength; 286 ystep=-yMul; 287 } 288 else 289 { 290 yTotal=simulatorParser.yEdgeLength*yMul; 291 ystep=1; 292 } 293 294 for( int x = 0; x< xTotal; x+=xstep) 295 { 296 for(int y = 0; y< yTotal; y+=ystep) 297 { 298 // String neu 299 // = layer.getPrefix()+","+x+","+y+","+layer.getSuffix(); 300 301 // if(pas.ls.cellmap.containsKey(neu)) 302 // { 303 304 int id; 305 306 id = simulatorParser.layerStructure.cellmap_slow ( 307 layer.getPrefix(),layer.getSuffix(),x,y ); 308 309 if(simulatorParser.layerStructure.neurons != null) 310 { 311 simulatorParser.layerStructure.neurons[ 312 id - simulatorParser.layerStructure.base].setRecord(true); 313 } 314 315 // } 316 // else 317 // { 318 // throw new RuntimeException("not in the grid"); 319 // } 320 321 } 322 } 323 } 324 325 /*********************************************************************** 326 * Add a line of neurons to be recorded 327 ***********************************************************************/ 328 public ArrayList<Integer> addLine ( 329 final int x1, 330 final int y1, 331 final int x2, 332 final int y2, 333 final String pre, 334 final String suf, 335 final ArrayList<String> names ) 336 //////////////////////////////////////////////////////////////////////// 337 { 338 final ArrayList<Integer> out = new ArrayList<Integer> ( ); 339 340// int xTotal=0; 341// 342// int yTotal=0; 343 344 int 345 xstep = 0, 346 ystep = 0; 347 348 final int 349 xMul = simulatorParser.layerStructure.getXmultiplier ( pre, suf ), 350 yMul = simulatorParser.layerStructure.getYmultiplier ( pre, suf ); 351 352 if ( xMul < 0 ) 353 { 354// xTotal=simulatorParser.xEdgeLength; 355 356 xstep = -xMul; 357 } 358 else 359 { 360// xTotal=simulatorParser.xEdgeLength*xMul; 361 362 xstep = 1; 363 } 364 365 if ( yMul < 0 ) 366 { 367// yTotal=simulatorParser.yEdgeLength; 368 369 ystep = -yMul; 370 } 371 else 372 { 373// yTotal=simulatorParser.yEdgeLength*yMul; 374 375 ystep = 1; 376 } 377 378 if ( x1 == x2 379 && y1 == y2 ) 380 { 381 final String neu = pre + "," + x1 + "," + y1 + "," + suf; 382 383 final int id = simulatorParser.layerStructure.cellmap_slow ( 384 pre, 385 suf, 386 x1, 387 y1 ); 388 389 if ( id != -1 ) 390 { 391 out.add ( id ); 392 393 names.add ( neu ); 394 395 if ( simulatorParser.layerStructure.neurons != null ) 396 { 397 simulatorParser.layerStructure.neurons [ id ].setRecord ( 398 true ); 399 } 400 } 401 402 return out; 403 } 404 405 int xBegin = x1 < x2 ? x1 : x2; 406 407 if ( xBegin % xstep != 0 ) 408 { 409 xBegin += xstep - xBegin % xstep; 410 } 411 412 int yBegin = y1 < y2 ? y1 : y2; 413 414 if ( yBegin % ystep != 0 ) 415 { 416 yBegin += ystep - yBegin % ystep; 417 } 418 419 if ( Math.abs ( x1 - x2 ) < Math.abs ( y1 - y2 ) ) 420 { 421 for ( int y = yBegin; y <= ( y1 > y2 ? y1 : y2 ); y += ystep ) 422 { 423 final double k = ( double ) ( x2 - x1 ) / ( double ) ( y2 - y1 ); 424 425 String neu = pre+","+ (int)(x1 + (double)(y-y1)*k)+","+y+","+suf; 426 427 int id; 428 429 if ( ( id = simulatorParser.layerStructure.cellmap_slow ( 430 pre, 431 suf, 432 ( int ) ( x1 + ( double ) ( y - y1 ) *k ), 433 y ) ) != -1 ) 434 { 435 out.add ( id ); 436 437 names.add ( neu ); 438 439 if ( simulatorParser.layerStructure.neurons != null ) 440 { 441 simulatorParser.layerStructure.neurons [ id ].setRecord ( 442 true ); 443 } 444 } 445 } 446 } 447 else 448 { 449 for ( int x = xBegin; x <= ( x1 > x2 ? x1 : x2 ); x += xstep ) 450 { 451 final double k = ( double ) ( y2 - y1 ) / ( double ) ( x2 - x1 ); 452 453 final String neu 454 = pre 455 + "," 456 + x 457 + "," 458 + ( int ) ( y1 + ( double ) ( x - x1 ) * k ) 459 + "," 460 + suf; 461 462 int id; 463 464 if ( ( id = simulatorParser.layerStructure.cellmap_slow ( 465 pre, 466 suf, 467 x, 468 ( int ) ( y1 + ( double ) ( x - x1 ) * k ) ) ) !=-1 ) 469 { 470 out.add ( id ); 471 472 names.add ( neu ); 473 474 if ( simulatorParser.layerStructure.neurons != null ) 475 { 476 simulatorParser.layerStructure.neurons [ id ].setRecord ( 477 true ); 478 } 479 } 480 } 481 } 482 483 return out; 484 } 485 486 /*********************************************************************** 487 * Add a square of neurons to be recorded. 488 * 489 * @param x1 490 * @param y1 491 * @param x2 492 * @param y2 493 * @param pre 494 * @param suf 495 * @param names 496 ***********************************************************************/ 497 public ArrayList<Integer> addSquare ( 498 final int x1, 499 final int y1, 500 final int x2, 501 final int y2, 502 final String pre, 503 final String suf, 504 final ArrayList<String> names ) 505 //////////////////////////////////////////////////////////////////////// 506 { 507 // LOGGER.trace ( "addSquare() entered" ); 508 509 final ArrayList<Integer> out = new ArrayList<Integer> ( ); 510 511 int xTotal=0; 512 513 int yTotal=0; 514 515 int xstep=0; 516 517 int ystep=0; 518 519 int xMul = simulatorParser.layerStructure.getXmultiplier(pre,suf); 520 521 int yMul = simulatorParser.layerStructure.getYmultiplier(pre,suf); 522 523 if(xMul < 0 ) 524 { 525 xTotal=simulatorParser.xEdgeLength; 526 527 xstep=-xMul; 528 } 529 else 530 { 531 xTotal=simulatorParser.xEdgeLength*xMul; 532 533 xstep=1; 534 } 535 536 if(yMul < 0 ) 537 { 538 yTotal=simulatorParser.yEdgeLength; 539 540 ystep=-yMul; 541 } 542 else 543 { 544 yTotal=simulatorParser.yEdgeLength*yMul; 545 546 ystep=1; 547 } 548 549 int xBegin = (x1<x2 ? x1: x2); 550 551 if(xBegin % xstep !=0) xBegin+= xstep - xBegin % xstep ; 552 553 int yBegin = (y1<y2 ? y1: y2); 554 555 if(yBegin % ystep !=0) yBegin+= ystep - yBegin % ystep ; 556 557 for( int x = xBegin ; x <= (x1>x2?x1:x2); x+=xstep) 558 { 559 for( int y = yBegin ; y <= (y1>y2?y1:y2); y+=ystep) 560 { 561 int id; 562 563 if ( ( id = simulatorParser.layerStructure.cellmap_slow ( 564 pre, 565 suf, 566 x, 567 y ) ) != -1 ) 568 { 569 out.add(id); 570 571 final String neu = pre + "," + x + "," + y + "," + suf; 572 573 names.add ( neu ); 574 575 if ( simulatorParser.layerStructure.neurons != null ) 576 { 577 simulatorParser.layerStructure.neurons [ id ].setRecord ( 578 true ); 579 } 580 581 // LOGGER.trace ( "Recording neuron id {}", id ); 582 } 583 } 584 } 585 586 return out; 587 } 588 589 /*********************************************************************** 590 * Add a line of neurons to be recorded 591 * 592 * @param x1 593 * @param y1 594 * @param x2 595 * @param y2 596 * @param pre 597 * @param suf 598 * @param hostId 599 * @param names 600 ***********************************************************************/ 601 public ArrayList<Integer> addLine ( 602 final int x1, 603 final int y1, 604 final int x2, 605 final int y2, 606 final String pre, 607 final String suf, 608 final int hostId, 609 final ArrayList<String> names ) 610 //////////////////////////////////////////////////////////////////////// 611 { 612 final ArrayList<Integer> out = new ArrayList<Integer>(); 613 614 int xTotal=0; 615 616 int yTotal=0; 617 618 int xstep=0; 619 620 int ystep=0; 621 622 int xMul=simulatorParser.layerStructure.getXmultiplier(pre,suf); 623 624 int yMul=simulatorParser.layerStructure.getYmultiplier(pre,suf); 625 626 if(xMul < 0 ) 627 { 628 xTotal=simulatorParser.xEdgeLength; 629 630 xstep=-xMul; 631 } 632 else 633 { 634 xTotal=simulatorParser.xEdgeLength*xMul; 635 636 xstep=1; 637 } 638 639 if(yMul < 0 ) 640 { 641 yTotal=simulatorParser.yEdgeLength; 642 643 ystep=-yMul; 644 } 645 else 646 { 647 yTotal=simulatorParser.yEdgeLength*yMul; 648 649 ystep=1; 650 } 651 652 if(x1==x2 && y1==y2) 653 { 654 String neu = pre+","+ x1+","+y1+","+suf; 655 656 int id = simulatorParser.layerStructure.cellmap_slow(pre,suf,x1,y1); 657 658 if(id!=-1) 659 { 660 if ( FunUtil.hostId ( 661 simulatorParser.layerStructure.nodeEndIndices, id ) 662 == hostId ) 663 { 664 out.add(id); 665 666 names.add(neu); 667 668 simulatorParser.layerStructure.neurons [ 669 id - simulatorParser.layerStructure.base].setRecord(true); 670 } 671 } 672 673 return out; 674 } 675 676 int xBegin = (x1<x2 ? x1: x2); 677 678 if(xBegin % xstep !=0) xBegin+= xstep - xBegin % xstep ; 679 680 int yBegin = (y1<y2 ? y1: y2); 681 682 if(yBegin % ystep !=0) yBegin+= ystep - yBegin % ystep ; 683 684 if( Math.abs(x1-x2)<Math.abs(y1-y2)) 685 { 686 for( int y = yBegin ; y <= (y1>y2?y1:y2); y+=ystep) 687 { 688 double k=(double)(x2-x1)/(double)(y2-y1); 689 690 String neu = pre+","+ (int)(x1 + (double)(y-y1)*k)+","+y+","+suf; 691 692 int id; 693 694 if ( ( id = simulatorParser.layerStructure.cellmap_slow ( 695 pre, 696 suf, 697 ( int ) ( x1 + ( double ) ( y - y1 ) * k ), 698 y ) ) !=-1 ) 699 { 700 if ( FunUtil.hostId ( 701 simulatorParser.layerStructure.nodeEndIndices, id ) 702 == hostId ) 703 { 704 out.add(id); 705 706 names.add(neu); 707 708 simulatorParser.layerStructure.neurons[ 709 id - simulatorParser.layerStructure.base].setRecord(true); 710 } 711 } 712 } 713 } 714 else 715 { 716 for( int x = xBegin ; x <= (x1>x2?x1:x2); x+=xstep) 717 { 718 double k=(double)(y2-y1)/(double)(x2-x1); 719 720 String neu = pre+","+ x+","+ (int)(y1 + (double)(x-x1)*k)+","+suf; 721 722 int id; 723 724 if ( ( id = simulatorParser.layerStructure.cellmap_slow ( 725 pre, 726 suf, 727 x, 728 ( int ) ( y1 + ( double ) ( x - x1 ) * k ) ) ) !=-1 ) 729 { 730 // id=pas.ls.cellmap.get(neu); 731 732 if ( FunUtil.hostId ( 733 simulatorParser.layerStructure.nodeEndIndices, id ) 734 == hostId ) 735 { 736 out.add(id); 737 738 names.add(neu); 739 740 simulatorParser.layerStructure.neurons [ 741 id-simulatorParser.layerStructure.base ].setRecord ( true ); 742 } 743 } 744 } 745 } 746 747 return out; 748 } 749 750 /*********************************************************************** 751 * Add a square of neurons to be recorded. 752 * 753 * @param x1 754 * @param y1 755 * @param x2 756 * @param y2 757 * @param pre 758 * @param suf 759 * @param hostId 760 * @param names 761 ***********************************************************************/ 762 public ArrayList<Integer> addSquare ( 763 final int x1, 764 final int y1, 765 final int x2, 766 final int y2, 767 final String pre, 768 final String suf, 769 final int hostId, 770 final ArrayList<String> names ) 771 //////////////////////////////////////////////////////////////////////// 772 { 773 // LOGGER.trace ( "addSquare(hostId) entered" ); 774 775 final ArrayList<Integer> out = new ArrayList<Integer>(); 776 777 int xTotal=0; 778 779 int yTotal=0; 780 781 int xstep=0; 782 783 int ystep=0; 784 785 int xMul=simulatorParser.layerStructure.getXmultiplier(pre,suf); 786 787 int yMul=simulatorParser.layerStructure.getYmultiplier(pre,suf); 788 789 if(xMul < 0 ) 790 { 791 xTotal=simulatorParser.xEdgeLength; 792 793 xstep=-xMul; 794 } 795 else 796 { 797 xTotal=simulatorParser.xEdgeLength*xMul; 798 799 xstep=1; 800 } 801 802 if(yMul < 0 ) 803 { 804 yTotal=simulatorParser.yEdgeLength; 805 806 ystep=-yMul; 807 } 808 else 809 { 810 yTotal=simulatorParser.yEdgeLength*yMul; 811 812 ystep=1; 813 } 814 815 int xBegin = (x1<x2 ? x1: x2); 816 817 if(xBegin % xstep !=0) xBegin+= xstep - xBegin % xstep ; 818 819 int yBegin = (y1<y2 ? y1: y2); 820 821 if(yBegin % ystep !=0) yBegin+= ystep - yBegin % ystep ; 822 823 for( int x = xBegin ; x <= (x1>x2?x1:x2); x+=xstep) 824 { 825 for( int y = yBegin ; y <= (y1>y2?y1:y2); y+=ystep) 826 { 827 String neu = pre+","+ x+","+y+","+suf; 828 829 int id = simulatorParser.layerStructure.cellmap_slow(pre,suf,x,y); 830 831 if(id!=-1) 832 { 833 if ( FunUtil.hostId ( 834 simulatorParser.layerStructure.nodeEndIndices, id ) 835 == hostId ) 836 { 837 out.add(id); 838 839 names.add(neu); 840 841 simulatorParser.layerStructure.neurons[ 842 id-simulatorParser.layerStructure.base].setRecord(true); 843 } 844 } 845 } 846 } 847 848 return out; 849 } 850 851 //////////////////////////////////////////////////////////////////////// 852 //////////////////////////////////////////////////////////////////////// 853 }