Package cnslab.cnsnetwork

Source Code of cnslab.cnsnetwork.Stimulus

    package cnslab.cnsnetwork;

    import java.io.*;
    import java.util.*;

    import cnslab.image.imageIO;
    import cnslab.image.Convolution;
    import cnslab.cnsmath.*;
    import edu.jhu.mb.ernst.model.ModelFactory;
    import edu.jhu.mb.ernst.model.Synapse;

    /***********************************************************************
    * Stimulus class contains all types of stimulus.
    *
    * The injected spikes are assumed to be inhomogeneous Poisson spikes,
    * similar to BKPoissonNeuron.
    *
    * @version
    *   $Date: 2012-08-04 20:43:22 +0200 (Sat, 04 Aug 2012) $
    *   $Rev: 104 $
    *   $Author: croft $
    * @author
    *   Yi Dong
    * @author
    *   David Wallace Croft, M.Sc.
    * @author
    *   Jeremy Cohen
    ***********************************************************************/
    public final class  Stimulus
      implements Serializable, Transmissible
    ////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////
    {

    private static final long
      serialVersionUID = 0L;

    // public variables

    public Seed  seed;

    public SimulatorParser  simulatorParser;

    // private variables

    private final ModelFactory  modelFactory;

    private final double
      strength,
      onTime,
      offTime,
      freq,
      decay; // the decay of the frequency

    /** array of neuron gets input. */
    private final List<Integer>
      neuronIndexList;

    private final List<Double>
      relativeStrengthList;

    // private ArrayList<Double> relativeStrH;

    // private ArrayList<Double> relativeStrV;

    private final int
      type,
      channel;

    ////////////////////////////////////////////////////////////////////////
    // constructor methods
    ////////////////////////////////////////////////////////////////////////

    public  Stimulus (
      final ModelFactory     modelFactory,
      final SimulatorParser  simulatorParser,
      final double           strength,
      final int              type,
      final double           onTime,
      final double           offTime,
      final double           freq,
      final double           decay,
      final Seed             seed,
      final int              channel )
    ////////////////////////////////////////////////////////////////////////
    {
      this.modelFactory = modelFactory;

      this.strength = strength;

      this.type = type;

      this.simulatorParser = simulatorParser;

      this.onTime = onTime;

      this.offTime = offTime;

      this.freq = freq;

      this.decay = decay;

      this.seed = seed;

      this.channel = channel;

      neuronIndexList = new ArrayList<Integer> ( );

      relativeStrengthList = new ArrayList<Double> ( );

      // relativeStrH= new ArrayList<Double>();
      // relativeStrV= new ArrayList<Double>();
    }

    ////////////////////////////////////////////////////////////////////////
    // accessor methods
    ////////////////////////////////////////////////////////////////////////

    public int getChannel  ( ) { return channel; }

    public double  getDecay    ( ) { return decay; }

    public double  getFreq     ( ) { return freq; }

    public double  getOffTime  ( ) { return offTime; }

    public double  getOnTime   ( ) { return onTime; }

    public double  getStrength ( ) { return strength; }   

    public int     getType     ( ) { return type; }

    ////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////

    public ArrayList<PInputEvent>  init ( final int  sourceID )
    ////////////////////////////////////////////////////////////////////////
   
      final ArrayList<PInputEvent>  out = new ArrayList<PInputEvent> ( );

      final int neuronIndexListSize = neuronIndexList.size ( );

      for ( int  i = 0; i < neuronIndexListSize; i++ )
      {
        final int toNeuronIndex = neuronIndexList.get ( i ).intValue ( );

        final double
          relativeStrength = relativeStrengthList.get ( i ).doubleValue ( );

        final double
          synapseStrength = relativeStrength * strength;

        final Synapse  synapse = modelFactory.createSynapse (
          toNeuronIndex,
          ( byte ) type,
          ( float ) synapseStrength );

        final double  time = getNextTime ( onTime );

        if ( time >= 0 )
        {
          out.add ( new PInputEvent ( time, synapse, sourceID ) );
        }
      }

      return out;
    }

/*
    public ArrayList<PInputEvent> initH(int sourceID)
    ////////////////////////////////////////////////////////////////////////
    { 
    ArrayList<PInputEvent> out = new ArrayList<PInputEvent>();
    Synapse syn;
    for(int i = 0 ; i < neuIndex.size();i++)
    {
      syn = new Synapse(neuIndex.get(i),relativeStrH.get(i)*strength,type);
      double time = getNextTime(onTime);
      if(time>=0)
      {
      out.add(new PInputEvent(time,syn,sourceID));
      }
    }
    return out;
    }

    public ArrayList<PInputEvent> initV(int sourceID)
    ////////////////////////////////////////////////////////////////////////
    { 
    ArrayList<PInputEvent> out = new ArrayList<PInputEvent>();
    Synapse syn;
    for(int i = 0 ; i < neuIndex.size();i++)
    {
      syn = new Synapse(neuIndex.get(i),relativeStrV.get(i)*strength,type);
      double time = getNextTime(onTime);
      if(time>=0)
      {
      out.add(new PInputEvent(time,syn,sourceID));
      }
    }
    return out;
    }
*/

    /***********************************************************************
    * Get the next time given current time.
    *
    * Inhomogeneous Poisson process.
    ***********************************************************************/
    public double  getNextTime ( final double  currTime )
    ////////////////////////////////////////////////////////////////////////
    {
      double  time = currTime;

      time += ( -Math.log ( Cnsran.ran2 ( seed ) ) / freq );

      while ( Cnsran.ran2 ( seed )
        > Math.exp ( -decay * ( time - onTime ) ) )
      {
        time += ( -Math.log ( Cnsran.ran2 ( seed ) ) / freq );

        if ( time > offTime )
        {
          return -1.0;
        }
      }

      if ( time > offTime )
      {
        return -1.0;
      }

      return time;
    }

    /***********************************************************************
    * Stimulate a square of neurons.
    *
    * @param x1
    * @param y1
    * @param x2
    * @param y2
    * @param pre
    * @param suf
    * @param hostId
    ***********************************************************************/
    public void  plotSquare (
      final int     x1,
      final int     y1,
      final int     x2,
      final int     y2,
      final String  pre,
      final String  suf,
      final int     hostId )
    ////////////////////////////////////////////////////////////////////////
    {
      int xTotal=0;

      int yTotal=0;

      int xstep=0;

      int ystep=0;

      int xMul=simulatorParser.layerStructure.getXmultiplier(pre,suf);

      int yMul=simulatorParser.layerStructure.getYmultiplier(pre,suf);

      if(xMul < 0 )
      {          
        xTotal=simulatorParser.xEdgeLength;
       
        xstep=-xMul;
      }
      else
      {      
        xTotal=simulatorParser.xEdgeLength*xMul;
       
        xstep=1;
      }
     
      if(yMul < 0 )
      {      
        yTotal=simulatorParser.yEdgeLength;
       
        ystep=-yMul;
      }
      else
      {      
        yTotal=simulatorParser.yEdgeLength*yMul;
       
        ystep=1;
      }

      if ( x1> xTotal || x2 > xTotal || y1> yTotal || y2> yTotal )
      {
        throw new RuntimeException("out of range error");
      }
   
      // Draw four non-overlapping lines

      final int xShift = x1 > x2 ? xstep : -xstep;

      final int yShift = y1 > y2 ? ystep : -ystep;

      plotLine( x1 , y1 , x1 , y2 + yShift, pre , suf , hostId );

      plotLine( x1 , y2 , x2 + xShift, y2 , pre , suf , hostId );

      plotLine( x2 , y2 , x2 , y1 - yShift, pre , suf , hostId );

      plotLine( x2 , y1 , x1 - xShift, y1 , pre , suf , hostId );
    }

    /***********************************************************************
    * Stimulate a filled square of neurons
    ***********************************************************************/
    public void  plotFilledSquare (
      final int     x1,
      final int     y1,
      final int     x2,
      final int     y2,
      final String  pre,
      final String  suf,
      final int     hostId )
    ////////////////////////////////////////////////////////////////////////
    {
      int xTotal=0;

      int yTotal=0;

      int xstep=0;

      int ystep=0;

      int xMul=simulatorParser.layerStructure.getXmultiplier(pre,suf);

      int yMul=simulatorParser.layerStructure.getYmultiplier(pre,suf);

      if(xMul < 0 )
      {          
        xTotal=simulatorParser.xEdgeLength;
        xstep=-xMul;
      }
      else
      {      
        xTotal=simulatorParser.xEdgeLength*xMul;
        xstep=1;
      }
      if(yMul < 0 )
      {      
        yTotal=simulatorParser.yEdgeLength;
        ystep=-yMul;
      }
      else
      {      
        yTotal=simulatorParser.yEdgeLength*yMul;
        ystep=1;
      }

      if ( x1> xTotal || x2 > xTotal || y1> yTotal || y2> yTotal )
      {
        throw new RuntimeException("out of range error");
      }


      for (int x = Math.min( x1 , x2 ); x <= Math.max( x1 , x2 ); x+= xstep)
      {
        plotLine( x , y1 , x, y2 , pre , suf , hostId );
      }
    }

    /***********************************************************************
    * Stimulate a line of neurons
    ***********************************************************************/
    public void  plotLine (
      final int     x1,
      final int     y1,
      final int     x2,
      final int     y2,
      final String  pre,
      final String  suf,
      final int     hostId )
    ////////////////////////////////////////////////////////////////////////
    {
      double length = Math.sqrt(
        (double)(x2-x1)*(double)(x2-x1) +
        (double)(y2-y1)*(double)(y2-y1));

      if(length < 1e-5// point stimulus
      {
        int id;

        if ( ( id = simulatorParser.layerStructure.cellmap_slow (
          pre, suf, x1, y1 ) ) != -1 )
        {
          if(FunUtil.hostId(
            simulatorParser.layerStructure.nodeEndIndices, id) ==  hostId)
          {
            relativeStrengthList.add(1.0);
            neuronIndexList.add(id);
          }
        }
        else
        {
          throw new RuntimeException("point is not in grid");
        }
        return;
      }

      int xTotal=0;

      int yTotal=0;

      int xstep=0;

      int ystep=0;

      int xMul=simulatorParser.layerStructure.getXmultiplier(pre,suf);

      int yMul=simulatorParser.layerStructure.getYmultiplier(pre,suf);

      if(xMul < 0 )
      {          
        xTotal=simulatorParser.xEdgeLength;
        xstep=-xMul;
      }
      else
      {      
        xTotal=simulatorParser.xEdgeLength*xMul;
        xstep=1;
      }
      if(yMul < 0 )
      {      
        yTotal=simulatorParser.yEdgeLength;
        ystep=-yMul;
      }
      else
      {      
        yTotal=simulatorParser.yEdgeLength*yMul;
        ystep=1;
      }

      if ( x1> xTotal || x2 > xTotal || y1> yTotal || y2> yTotal )
      {
        throw new RuntimeException("out of range error");
      }

      // Here we determine the neurons that are "hit" by the line.
      // See the Wikipedia page on Bresenham's line algorithm.

      // If steep, swap x's and y's.
      boolean steep = Math.abs(y2 - y1) > Math.abs(x2 - x1);
      int _xBegin, _xEnd, _yBegin, _yEnd;
      if (!steep)
      {
        _xBegin = x1;
        _xEnd = x2;
        _yBegin = y1;
        _yEnd = y2;
      }
      else
      {
        _xBegin = y1;
        _xEnd = y2;
        _yBegin = x1;
        _yEnd = x2;
      }

      // If flipped, swap begins and ends.
      boolean flipped = _xBegin > _xEnd;
      int xBegin, xEnd, yBegin, yEnd;
      if (!flipped)
      {
        xBegin = _xBegin;
        xEnd = _xEnd;
        yBegin = _yBegin;
        yEnd = _yEnd;
      }
      else
      {
        xBegin = _xEnd;
        xEnd = _xBegin;
        yBegin = _yEnd;
        yEnd = _yBegin;
      }

      if(xBegin % xstep !=0) xBegin+= xstep - xBegin % xstep ;
      if(yBegin % ystep !=0) yBegin+= ystep - yBegin % ystep ;

      double slope = (double) (yEnd - yBegin) / (double) (xEnd - xBegin);

      for (int x = xBegin; x <= xEnd; x += xstep)
      { 
        int y =  (int) Math.round(yBegin + slope * (x - xBegin));
        y = y - (y % ystep);

        // If steep, swap x's and y's
        int xNeuron = steep ? y : x;
        int yNeuron = steep ? x : y;

        int id = simulatorParser.layerStructure.cellmap_slow(
          pre,suf,xNeuron, yNeuron);

        if(id != -1)
        {     
          if(FunUtil.hostId(
            simulatorParser.layerStructure.nodeEndIndices, id) ==  hostId)
          {
            // Calculate the shortest distance from the point
            // (xNeuron, yNeuron) to the line between (x1, y1) and (x2, y2)
           
            double distance = Math.abs((x2 - x1) * (y1 - yNeuron)
              - (x1 - xNeuron) * (y2 - y1)) / length;

            if(channel<0) // If there is no specified channel
            {
              // The relative strength of the synapse between this stimulus
              // and a neuron is a function [ distanceTune() ]
              // of the distance between the neuron and the line.
             
              relativeStrengthList.add( distanceTune ( distance ) );
            }
            else if(channel >=0 && channel <= 180)
            {
              double lineAngle = Math.acos((double)(x2-x1)/length);

              double  channelAngle
                = (double) channel * (Math.PI / (double) 180.0);

              relativeStrengthList.add (
                distanceTune (
                  distance * Math.cos(lineAngle - channelAngle) ) );
            }
            else
            {
              throw new RuntimeException (
                "channel range error (0-180 or <0)" );
            }

            neuronIndexList.add(id);
          }
        }
      }
    }

    /***********************************************************************
    *  Given image file, stimulate the layer of neurons accourding to image
    *  intensity
    ***********************************************************************/
    public void  plotImg (
      final String          pre,
      final String          suf,
      final String          filename,
      final double [ ] [ ]  filter )
    ////////////////////////////////////////////////////////////////////////
    {
      int [][] out;
      imageIO imgIO = new imageIO();
      out = imgIO.loadBWImage("imagelib/"+filename);
      int [][] pic = Convolution.convolve_safe(out,filter);

      int height = pic.length;
      int width = pic[0].length;

      int xstep,ystep;
      int xmulti,ymulti;
      xmulti = simulatorParser.layerStructure.getXmultiplier(pre,suf);
      ymulti = simulatorParser.layerStructure.getYmultiplier(pre,suf);

      int xreso,yreso;

      if(xmulti>0)
      {      
        xstep=1;
        xreso=xmulti*simulatorParser.xEdgeLength;
      }
      else
      {      
        xstep=-xmulti;
        xreso=simulatorParser.xEdgeLength;
      }

      if(ymulti>0)
      {      
        ystep=1;
        yreso=ymulti*simulatorParser.yEdgeLength;
      }
      else
      {      
        ystep=-ymulti;
        yreso=simulatorParser.yEdgeLength;
      }

      double heightRatio;
      double widthRatio;

      try {
        heightRatio = (double)height/(double)(yreso/ystep);
        widthRatio = (double)width/(double)(xreso/xstep);

      }
      catch(Exception ex) {
        throw new RuntimeException("Pre:"+pre+" Suf:"+suf);
      }


      for( int x = ; x <  xreso/xstep;  x++)
      {
        for( int y = ; y < yreso/ystep;  y++)
        {
          // String neu = pre+","+x*xstep+","+ (yreso-y*ystep-1)+","+suf;

          if ( pic [ ( int ) ( y * heightRatio ) + ystep - 1 ]
            [ ( int ) ( x * widthRatio  ) ] < 0 )
          {
            pic[(int)(y*heightRatio)+ystep-1][(int)(x*widthRatio)]=0;
          }

          if ( pic [ ( int ) ( y * heightRatio ) + ystep - 1 ]
            [ ( int ) ( x * widthRatio  ) ] > 255 )
          {
            pic[(int)(y*heightRatio)+ystep-1][(int)(x*widthRatio)]=255;
          }

          // double pixel = (double)(pic[(int)((y)*heightRatio
          // +(int)(heightRatio/2.0))][(int)((x)*widthRatio
          // +(int)(widthRatio/2.0))])/(double)256;

          final double
          pixel = ( double ) (
            pic [ ( int ) ( y * heightRatio ) + ystep - 1 ]
              [ ( int ) ( x * widthRatio  ) ] ) / ( double ) 256;

          if ( pixel > 0.01 )
          {
            relativeStrengthList.add(pixel);

            neuronIndexList.add (
              simulatorParser.layerStructure.cellmap_slow (
                pre,
                suf,
                x * xstep,
                ( yreso - y * ystep - ystep ) ) );
          }
        }
      }
    }

    /***********************************************************************
    * Given image file, stimulate the layer of neurons accourding to reverse
    * of image intensity.
    ***********************************************************************/
    public void  plotRImg (
      final String  pre,
      final String  suf,
      final String  filename,
      final double [ ] [ ]  filter ) //plot reverse img
    ////////////////////////////////////////////////////////////////////////
    {
      //pas.xEdgeLength;
      //pas.yEdgeLength;
      int [][] out;
      imageIO imgIO = new imageIO();
      out = imgIO.loadBWImage("imagelib/"+filename);
      for(int i=0;i<out.length;i++)
      {
        for(int j=0;j<out[0].length;j++)
        {
          out[i][j]=255-out[i][j];
        }
      }
      int [][] pic = Convolution.convolve_safe(out,filter);
      int height = pic.length;
      int width = pic[0].length;

      int xstep,ystep;
      int xmulti,ymulti;
      xmulti = simulatorParser.layerStructure.getXmultiplier(pre,suf);
      ymulti = simulatorParser.layerStructure.getYmultiplier(pre,suf);

      int xreso,yreso;

      if(xmulti>0)
      {      
        xstep=1;
        xreso=xmulti*simulatorParser.xEdgeLength;
      }
      else
      {      
        xstep=-xmulti;
        xreso=simulatorParser.xEdgeLength;
      }

      if(ymulti>0)
      {      
        ystep=1;
        yreso=ymulti*simulatorParser.yEdgeLength;
      }
      else
      {      
        ystep=-ymulti;
        yreso=simulatorParser.yEdgeLength;
      }

      double heightRatio = (double)height/(double)(yreso/ystep);
      double widthRatio = (double)width/(double)(xreso/xstep);

      for( int x = ; x <  xreso/xstep;  x++)
      {
        for( int y = ; y < yreso/ystep;  y++)
        {
          // String neu = pre+","+x+","+ (pas.yEdgeLength-y-1)+","+suf;

          if ( pic [ ( int ) ( y * heightRatio ) + ystep - 1 ]
            [ ( int ) ( x * widthRatio  ) ] < 0 )
          {
            pic[(int)(y*heightRatio)+ystep-1][(int)(x*widthRatio)]=0;
          }

          if ( pic [ ( int ) ( y * heightRatio ) + ystep - 1 ]
            [ ( int ) ( x * widthRatio  ) ] > 255 )
          {
            pic[(int)(y*heightRatio)+ystep-1][(int)(x*widthRatio)]=255;
          }

          final double  pixel = ( double ) (
            pic [ ( int ) ( y * heightRatio ) + ystep - 1 ]
              [ ( int ) ( x * widthRatio  ) ] ) / ( double ) 256;

          //System.out.println("Layer pre:"+pre+" suf:"+suf+" heightRaito"
          // +heightRatio+"X:"+(int)(y*heightRatio+ystep-1)+"_"+(x*xstep)
          // +"Y:"+(int)(x*widthRatio)+"_"+(yreso-y*ystep-ystep)+" rate:"
          // +(double)(pic[(int)(y*heightRatio)+ystep-1]
          // [(int)(x*widthRatio)])/(double)256+" fin X:"+x+" Y:"+y);

          if ( pixel > 0.01 )
          {
            relativeStrengthList.add ( pixel );

            neuronIndexList.add (
              simulatorParser.layerStructure.cellmap_slow (
                pre,
                suf,
                x*xstep,
                ( yreso-y*ystep-ystep ) ) );
          }
        }
      }
    }

    /***********************************************************************
    * Stimulate the layer of neurons with a given matrix.
    *
    * cenX, cenY defines the center position of the matrix in the layer
    ***********************************************************************/
    public void  plotMatrix (
      final String          pre,
      final String          suf,
      final int             cenX,
      final int             cenY,
      final double [ ] [ ]  matrix,
      final int             hostId )
    ////////////////////////////////////////////////////////////////////////
    {
      final int [ ]  center = simulatorParser.layerStructure.closePoint (
        cenX,
        cenY,
        pre,
        suf );

      int halfMaX = matrix.length/2;
      int halfMaY = matrix[0].length/2;

      int xstep,ystep;
      int xmulti,ymulti;
      xmulti = simulatorParser.layerStructure.getXmultiplier(pre,suf);
      ymulti = simulatorParser.layerStructure.getYmultiplier(pre,suf);

      int xreso,yreso;

      if(xmulti>0)
      {      
        xstep=1;
        xreso=xmulti*simulatorParser.xEdgeLength;
      }
      else
      {      
        xstep=-xmulti;
        xreso=simulatorParser.xEdgeLength;
      }

      if(ymulti>0)
      {      
        ystep=1;
        yreso=ymulti*simulatorParser.yEdgeLength;
      }
      else
      {      
        ystep=-ymulti;
        yreso=simulatorParser.yEdgeLength;
      }

      for (
        int  x = center [ 0 ] - halfMaX;
        x < center [ 0 ]
          + ( matrix.length % 2 == 0 ? halfMaX : halfMaX + 1 );
        x++ )
      {
        for (
          int  y = center [ 1 ] - halfMaY;
          y < center [ 1 ]
            + ( matrix [ 0 ].length % 2 == 0 ? halfMaY : halfMaY + 1 );
          y++ )
        {
          int MaX=x-center[0]+halfMaX;
          int MaY=y-center[1]+halfMaY;
          int xx,yy;
          xx=x%xreso;
          yy=y%yreso;
          if(xx<0)xx=xx+xreso;
          if(yy<0)yy=yy+yreso;

          final int  id = simulatorParser.layerStructure.cellmap_slow (
            pre,
            suf,
            xx,
            yy );

          if(id != -1)
          {
            if ( FunUtil.hostId (
              simulatorParser.layerStructure.nodeEndIndices,
              id ) ==  hostId )
            {
              double pixel = matrix[MaX][MaY];

              if(pixel!=0.0)
              {
                relativeStrengthList.add(pixel);
                neuronIndexList.add(id);
              }
            }
          }
        }
      }
    }

    public void  plotMatrix (
      final String          pre,
      final String          suf,
      final int             cenX,
      final int             cenY,
      final double [ ] [ ]  matrix )
    ////////////////////////////////////////////////////////////////////////
    {
      final int [ ]  center = simulatorParser.layerStructure.closePoint (
        cenX,
        cenY,
        pre,
        suf );

      int halfMaX = matrix.length/2;

      int halfMaY = matrix[0].length/2;

      int xstep,ystep;
      int xmulti,ymulti;
      xmulti = simulatorParser.layerStructure.getXmultiplier(pre,suf);
      ymulti = simulatorParser.layerStructure.getYmultiplier(pre,suf);

      int xreso,yreso;

      if(xmulti>0)
      {      
        xstep=1;
        xreso=xmulti*simulatorParser.xEdgeLength;
      }
      else
      {      
        xstep=-xmulti;
        xreso=simulatorParser.xEdgeLength;
      }

      if(ymulti>0)
      {      
        ystep=1;
        yreso=ymulti*simulatorParser.yEdgeLength;
      }
      else
      {      
        ystep=-ymulti;
        yreso=simulatorParser.yEdgeLength;
      }

      for (
        int  x = center [ 0 ] - halfMaX;
        x < center [ 0 ]
          + ( matrix.length % 2 == 0 ? halfMaX : halfMaX + 1 );
        x++ )
      {
        for (
          int  y = center [ 1 ] - halfMaY;
          y < center [ 1 ]
            + ( matrix [ 0 ].length % 2 == 0 ? halfMaY : halfMaY + 1 );
          y++ )
        {
          int MaX=x-center[0]+halfMaX;
          int MaY=y-center[1]+halfMaY;
          int xx,yy;
          xx=x%xreso;
          yy=y%yreso;
          if(xx<0)xx=xx+xreso;
          if(yy<0)yy=yy+yreso;

          final int  id = simulatorParser.layerStructure.cellmap_slow (
            pre,
            suf,
            xx,
            yy );

          if(id != -1)
          {
            double pixel = matrix[MaX][MaY];
            if(pixel!=0.0)
            {
              relativeStrengthList.add(pixel);
              neuronIndexList.add(id);
            }
          }
        }
      }
    }

    /***********************************************************************
    * Stimulate the whole layer of neurons.
    *
    * Injecting noise to the whole layer.
    ***********************************************************************/
    public void  background (
      final String  pre,
      final String  suf )
    ////////////////////////////////////////////////////////////////////////
    {
      int
        xTotal = 0,
        yTotal = 0,
        xstep  = 0,
        ystep  = 0,
        xMul   = simulatorParser.layerStructure.getXmultiplier ( pre, suf ),
        yMul   = simulatorParser.layerStructure.getYmultiplier ( pre, suf );

      if ( xMul < 0 )
      {          
        xTotal = simulatorParser.xEdgeLength;

        xstep = -xMul;
      }
      else
      {      
        xTotal = simulatorParser.xEdgeLength * xMul;

        xstep = 1;
      }

      if ( yMul < 0 )
      {      
        yTotal = simulatorParser.yEdgeLength;

        ystep = -yMul;
      }
      else
      {      
        yTotal = simulatorParser.yEdgeLength * yMul;

        ystep = 1;
      }

      for ( int  x = 0; x < xTotal; x = x + xstep )
      {
        for ( int  y = 0; y < yTotal; y = y + ystep )
        {
          relativeStrengthList.add ( Double.valueOf ( 1.0 ) );

          neuronIndexList.add (
            simulatorParser.layerStructure.cellmap_slow (
              pre,
              suf,
              x,
              y ) );
        }
      }
    }

    /***********************************************************************
    * Injecting noise to the whole layer.
    ***********************************************************************/
    public void  background (
      final String  pre,
      final String  suf,
      final int     hostId )
    ////////////////////////////////////////////////////////////////////////
    {
      int xTotal=0;          
      int yTotal=0;
      int xstep=0;
      int ystep=0;
      int xMul=simulatorParser.layerStructure.getXmultiplier(pre,suf);
      int yMul=simulatorParser.layerStructure.getYmultiplier(pre,suf);


      if(xMul < 0 )
      {          
        xTotal=simulatorParser.xEdgeLength;
        xstep=-xMul;
      }
      else
      {      
        xTotal=simulatorParser.xEdgeLength*xMul;
        xstep=1;
      }
      if(yMul < 0 )
      {      
        yTotal=simulatorParser.yEdgeLength;
        ystep=-yMul;
      }
      else
      {      
        yTotal=simulatorParser.yEdgeLength*yMul;
        ystep=1;
      }


      for( int x = ; x < xTotal;  x=x+xstep)
      {
        for( int y = ; y < yTotal ; y=y+ystep)
        {
          //        String neu = pre+","+x+","+ y+","+suf;
          int id = simulatorParser.layerStructure.cellmap_slow(pre,suf,x,y);

          if ( FunUtil.hostId (
            simulatorParser.layerStructure.nodeEndIndices,
            id ) == hostId )
          {
            relativeStrengthList.add(1.0);

            neuronIndexList.add (
              simulatorParser.layerStructure.cellmap_slow (
                pre,
                suf,
                x,
                y ) );
          }
        }
      }
    }

    /***********************************************************************
    * Plot reverse image.
    ***********************************************************************/
    public void plotRImg (
      final String          pre,
      final String          suf,
      final String          filename,
      final double [ ] [ ]  filter,
      final double          gamma,
      final double          k,
      final int             hostId )
    ////////////////////////////////////////////////////////////////////////
    {
      //pas.xEdgeLength;
      //pas.yEdgeLength;
      int [][] out;
      imageIO imgIO = new imageIO();

      out = imgIO.loadBWImage("imagelib/"+filename);

      for(int i=0;i<out.length;i++)
      {
        for(int j=0;j<out[0].length;j++)
        {
          out[i][j]=255-out[i][j];
        }
      }
      int [][] pic = Convolution.convolve_safe(out,filter);
      int height = pic.length;
      int width = pic[0].length;

      int xstep,ystep;
      int xmulti,ymulti;
      xmulti = simulatorParser.layerStructure.getXmultiplier(pre,suf);
      ymulti = simulatorParser.layerStructure.getYmultiplier(pre,suf);

      int xreso,yreso;

      if(xmulti>0)
      {      
        xstep=1;
        xreso=xmulti*simulatorParser.xEdgeLength;
      }
      else
      {      
        xstep=-xmulti;
        xreso=simulatorParser.xEdgeLength;
      }

      if(ymulti>0)
      {      
        ystep=1;
        yreso=ymulti*simulatorParser.yEdgeLength;
      }
      else
      {      
        ystep=-ymulti;
        yreso=simulatorParser.yEdgeLength;
      }

      double heightRatio = (double)height/(double)(yreso/ystep);
      double widthRatio = (double)width/(double)(xreso/xstep);

      for( int x = ; x <  xreso/xstep;  x++)
      {
        for( int y = ; y < yreso/ystep;  y++)
        {
          // String neu = pre+","+x+","+ (pas.yEdgeLength-y-1)+","+suf;

          int id = simulatorParser.layerStructure.cellmap_slow (
            pre,
            suf,
            x*xstep,
            (yreso-y*ystep-ystep));

          if ( FunUtil.hostId (
            simulatorParser.layerStructure.nodeEndIndices,
            id ) ==  hostId )
            // if(pas.ls.cellmap.containsKey(neu))
          {
            // if(pic[(int)(y*heightRatio+ystep-1)]
            //       [(int)(x*widthRatio)]<0)
            // pic[(int)(y*heightRatio+ystep-1)][(int)(x*widthRatio)]=0;

            // if(pic[(int)(y*heightRatio+ystep-1)]
            //       [(int)(x*widthRatio)]>255)
            //   pic[(int)(y*heightRatio+ystep-1)][(int)(x*widthRatio)]=255;

            // double pixel = (double)(
            // 255-pic[(int)(y*heightRatio)]
            // [(int)(x*widthRatio)])/(double)256;

            double pixel = 0.0;

            int ii,jj;

            for(ii=0;ii<ystep;ii++)
            {
              for(jj=0;jj<xstep;jj++)
              {
                if ( pic [ ( int ) ( y * heightRatio ) + ystep - 1 - ii ]
                  [ ( int ) ( x * widthRatio  ) + jj ] < 0 )
                {
                  pic [ ( int ) ( y * heightRatio ) + ystep - 1 - ii ]
                    [ ( int ) ( x * widthRatio  ) + jj ] = 0;
                }

                if ( pic [ ( int ) ( y * heightRatio ) + ystep - 1 - ii ]
                  [ ( int ) ( x * widthRatio  ) + jj ] > 255 )
                {
                  pic [ ( int ) ( y * heightRatio ) + ystep - 1 - ii ]
                    [ ( int ) ( x * widthRatio  ) + jj ] = 255;
                }

                pixel += nonlinearFilter (
                  ( double ) ( pic
                    [ ( int ) ( y * heightRatio ) + ystep - 1 - ii ]
                      [ ( int ) ( x * widthRatio  ) + jj ] )
                      / ( double ) 256,
                      gamma,
                      k );
              }
            }

            pixel = pixel /(double)(ystep*xstep);

            // double pixel = (double)(pic[(int)(y*heightRatio)]
            // [(int)(x*widthRatio)])/(double)256;

            if(pixel>0.01)
            {
              relativeStrengthList.add(pixel);
              neuronIndexList.add(id);
            }
          }
        }
      }
    }

    /***********************************************************************
    * Non linear filter to simualte Retina
    *
    * @param x
    * @param gamma
    * @param k
    * @return
    ***********************************************************************/
    public double nonlinearFilter(double x, double gamma, double k)
    ////////////////////////////////////////////////////////////////////////
    {
      //    double gamma = 1.0;
      //    double k=0.02;
      if(gamma>0)
      {
        double var = Math.pow((x/k),gamma);

        return var/(1+var);
      }

      return x;
    }

    public void  plotImg (
      final String          pre,
      final String          suf,
      final String          filename,
      final double [ ] [ ]  filter,
      final double          gamma,
      final double          k,
      final int             hostId )
    ////////////////////////////////////////////////////////////////////////
    {
      //pas.xEdgeLength;
      //pas.yEdgeLength;
      int [][] out;
      imageIO imgIO = new imageIO();
      out = imgIO.loadBWImage("imagelib/"+filename);
      int [][] pic = Convolution.convolve_safe(out,filter);

      int height = pic.length;
      int width = pic[0].length;

      int xstep,ystep;
      int xmulti,ymulti;
      xmulti = simulatorParser.layerStructure.getXmultiplier(pre,suf);
      ymulti = simulatorParser.layerStructure.getYmultiplier(pre,suf);

      int xreso,yreso;

      if(xmulti>0)
      {      
        xstep=1;
        xreso=xmulti*simulatorParser.xEdgeLength;
      }
      else
      {      
        xstep=-xmulti;
        xreso=simulatorParser.xEdgeLength;
      }

      if(ymulti>0)
      {      
        ystep=1;
        yreso=ymulti*simulatorParser.yEdgeLength;
      }
      else
      {      
        ystep=-ymulti;
        yreso=simulatorParser.yEdgeLength;
      }

      double heightRatio = (double)height/(double)(yreso/ystep);

      double widthRatio  = (double)width /(double)(xreso/xstep);

      for( int x = ; x <  xreso/xstep;  x++)
      {
        for( int y = ; y < yreso/ystep;  y++)
        {
          // String neu = pre+","+x+","+ (pas.yEdgeLength-y-1)+","+suf;

          int id = simulatorParser.layerStructure.cellmap_slow(
            pre,
            suf,
            x*xstep,
            (yreso-y*ystep-ystep));

          if ( FunUtil.hostId (
            simulatorParser.layerStructure.nodeEndIndices,
            id ) ==  hostId )
            // if(pas.ls.cellmap.containsKey(neu))
          {
            // double pixel = (double)(255-pic[(int)(y*heightRatio)]
            // [(int)(x*widthRatio)])/(double)256;

            // double pixel = nonlinearFilter((double)(
            // pic[(int)(y*heightRatio)+ystep-1]
            // [(int)(x*widthRatio)])/(double)256,gamma,k);

            double pixel = 0.0;

            int ii,jj;

            for(ii=0;ii<ystep;ii++)
            {
              for(jj=0;jj<xstep;jj++)
              {
                if ( pic [ ( int ) ( y * heightRatio ) + ystep - 1 - ii ]
                  [ ( int ) ( x * widthRatio  ) + jj ] < 0 )
                {
                  pic [ ( int ) ( y * heightRatio ) + ystep - 1 - ii ]
                    [ ( int ) ( x * widthRatio  ) + jj ] = 0;
                }

                if ( pic [ ( int ) ( y * heightRatio ) + ystep - 1 - ii ]
                  [ ( int ) ( x * widthRatio  ) + jj ] > 255 )
                {
                  pic [ ( int ) ( y * heightRatio ) + ystep - 1 - ii ]
                    [ ( int ) ( x * widthRatio  ) + jj ] = 255;
                }

                pixel += nonlinearFilter (
                  ( double ) ( pic
                    [ ( int ) ( y * heightRatio ) + ystep - 1 - ii ]
                      [ ( int ) ( x * widthRatio  ) +jj ] )
                      / ( double ) 256,
                      gamma,
                      k );
              }
            }

            pixel = pixel / ( double ) ( ystep * xstep );

            if ( pixel > 0.01 )
            {
              relativeStrengthList.add ( pixel );

              neuronIndexList.add ( id );
            }
          }
        }
      }
    }

    public void  plotSquare (
      final int     x1,
      final int     y1,
      final int     x2,
      final int     y2,
      final String  pre,
      final String  suf )
    ////////////////////////////////////////////////////////////////////////
    {
      int xTotal=0;

      int yTotal=0;

      int xstep=0;

      int ystep=0;

      int xMul=simulatorParser.layerStructure.getXmultiplier(pre,suf);

      int yMul=simulatorParser.layerStructure.getYmultiplier(pre,suf);

      if(xMul < 0 )
      {          
        xTotal=simulatorParser.xEdgeLength;
        xstep=-xMul;
      }
      else
      {      
        xTotal=simulatorParser.xEdgeLength*xMul;
        xstep=1;
      }
      if(yMul < 0 )
      {      
        yTotal=simulatorParser.yEdgeLength;
        ystep=-yMul;
      }
      else
      {      
        yTotal=simulatorParser.yEdgeLength*yMul;
        ystep=1;
      }

      if ( x1> xTotal || x2 > xTotal || y1> yTotal || y2> yTotal )
      {
        throw new RuntimeException("out of range error");
      }

      // Draw four non-overlapping lines

      final int xShift = x1 > x2 ? xstep : -xstep;

      final int yShift = y1 > y2 ? ystep : -ystep;

      plotLine( x1 , y1 , x1 , y2 + yShift, pre , suf );

      plotLine( x1 , y2 , x2 + xShift, y2 , pre , suf );

      plotLine( x2 , y2 , x2 , y1 - yShift, pre , suf );

      plotLine( x2 , y1 , x1 - xShift, y1 , pre , suf );
    }

    public void  plotFilledSquare (
      final int     x1,
      final int     y1,
      final int     x2,
      final int     y2,
      final String  pre,
      final String  suf )
    ////////////////////////////////////////////////////////////////////////
    {
      int xTotal=0;

      int yTotal=0;

      int xstep=0;

      int ystep=0;

      int xMul=simulatorParser.layerStructure.getXmultiplier(pre,suf);

      int yMul=simulatorParser.layerStructure.getYmultiplier(pre,suf);

      if(xMul < 0 )
      {          
        xTotal=simulatorParser.xEdgeLength;
        xstep=-xMul;
      }
      else
      {      
        xTotal=simulatorParser.xEdgeLength*xMul;
        xstep=1;
      }
      if(yMul < 0 )
      {      
        yTotal=simulatorParser.yEdgeLength;
        ystep=-yMul;
      }
      else
      {      
        yTotal=simulatorParser.yEdgeLength*yMul;
        ystep=1;
      }

      if ( x1> xTotal || x2 > xTotal || y1> yTotal || y2> yTotal )
      {
        throw new RuntimeException("out of range error");
      }


      for (int x = Math.min( x1 , x2 ); x <= Math.max( x1 , x2 ); x+= xstep)
      {
        plotLine( x , y1 , x, y2 , pre , suf );
      }
    }

    public void  plotLine (
      final int     x1,
      final int     y1,
      final int     x2,
      final int     y2,
      final String  pre,
      final String  suf )
    ////////////////////////////////////////////////////////////////////////
    {   
      double length = Math.sqrt(
        (double)(x2-x1)*(double)(x2-x1)+
        (double)(y2-y1)*(double)(y2-y1));

      if(length < 1e-5// point stimulus
      {
        int id;
        if ( ( id = simulatorParser.layerStructure.cellmap_slow (
          pre, suf, x1, y1 ) ) != -1 )
        {
          relativeStrengthList.add(1.0);
          neuronIndexList.add(id);
        }
        else
        {
          throw new RuntimeException("point is not in grid");
        }
        return;
      }

      int xTotal=0;

      int yTotal=0;

      int xstep=0;

      int ystep=0;

      int xMul=simulatorParser.layerStructure.getXmultiplier(pre,suf);

      int yMul=simulatorParser.layerStructure.getYmultiplier(pre,suf);

      if(xMul < 0 )
      {          
        xTotal=simulatorParser.xEdgeLength;
        xstep=-xMul;
      }
      else
      {      
        xTotal=simulatorParser.xEdgeLength*xMul;
        xstep=1;
      }
      if(yMul < 0 )
      {      
        yTotal=simulatorParser.yEdgeLength;
        ystep=-yMul;
      }
      else
      {      
        yTotal=simulatorParser.yEdgeLength*yMul;
        ystep=1;
      }

      if ( x1> xTotal || x2 > xTotal || y1> yTotal || y2> yTotal )
      {
        throw new RuntimeException("out of range error");
      }

      // Here we determine the neurons that are "hit" by the line.
      // See the Wikipedia page on Bresenham's line algorithm.

      // If steep, swap x's and y's.
      boolean steep = Math.abs(y2 - y1) > Math.abs(x2 - x1);
      int _xBegin, _xEnd, _yBegin, _yEnd;
      if (!steep)
      {
        _xBegin = x1;
        _xEnd = x2;
        _yBegin = y1;
        _yEnd = y2;
      }
      else
      {
        _xBegin = y1;
        _xEnd = y2;
        _yBegin = x1;
        _yEnd = x2;
      }

      // If flipped, swap begins and ends.
      boolean flipped = _xBegin > _xEnd;
      int xBegin, xEnd, yBegin, yEnd;
      if (!flipped)
      {
        xBegin = _xBegin;
        xEnd = _xEnd;
        yBegin = _yBegin;
        yEnd = _yEnd;
      }
      else
      {
        xBegin = _xEnd;
        xEnd = _xBegin;
        yBegin = _yEnd;
        yEnd = _yBegin;
      }

      if(xBegin % xstep !=0) xBegin+= xstep - xBegin % xstep ;
      if(yBegin % ystep !=0) yBegin+= ystep - yBegin % ystep ;

      double slope = (double) (yEnd - yBegin) / (double) (xEnd - xBegin);

      for (int x = xBegin; x <= xEnd; x += xstep)
      { 
        int y =  (int) Math.round(yBegin + slope * (x - xBegin));
        y = y - (y % ystep);

        // If steep, swap x's and y's
        int xNeuron = steep ? y : x;
        int yNeuron = steep ? x : y;

        int id = simulatorParser.layerStructure.cellmap_slow(
          pre,suf,xNeuron, yNeuron);

        if(id != -1)
        {       
          // Calculate the shortest distance from the
          // point (xNeuron, yNeuron) to the
          // line between (x1, y1) and (x2, y2)
         
          double distance = Math.abs(
            (x2 - x1) * (y1 - yNeuron) -
            (x1 - xNeuron) * (y2 - y1)) / length;

          if(channel<0) // If there is no specified channel
          {
            // The relative strength of the synapse between this stimulus
            // and a neuron is a function [ distanceTune() ]
            // of the distance between the neuron and the line.
            relativeStrengthList.add( distanceTune ( distance ) );
          }
          else if(channel >=0 && channel <= 180)
          {
            double lineAngle = Math.acos((double)(x2-x1)/length);

            double
              channelAngle = (double) channel * (Math.PI / (double) 180.0);

            relativeStrengthList.add (
              distanceTune (
                distance * Math.cos(lineAngle - channelAngle) ) );
          }
          else
          {
            throw new RuntimeException (
              "channel range error (0-180 or <0)" );
          }

          neuronIndexList.add(id);
        }
      }
    }

    private double distanceTune (double d)
    ////////////////////////////////////////////////////////////////////////
    {
      return 1 - Math.sqrt(2) * d;
    }

    ////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////
    }
TOP

Related Classes of cnslab.cnsnetwork.Stimulus

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.