001    package cnslab.cnsnetwork;
002    
003    import java.io.*;
004    import java.util.*;
005    
006    import cnslab.cnsmath.*;
007    import edu.jhu.mb.ernst.model.Synapse;
008    import edu.jhu.mb.ernst.util.slot.Slot;
009
010    /***********************************************************************
011    * Sensory neuron fire according to user provided file. 
012    * 
013    * <p>
014    * If the data file ends in ".txt", the file will be assumed to be a text
015    * data file in the format described in the documentation for class
016    * RecorderDataLib and the data file path will be constructed relative to
017    * the "model" subdirectory.
018    * </p>
019    * <p>
020    * If the data file does not end in ".txt", the file will be assumed to
021    * be a binary data file and the data file path will be constructed
022    * relative to the "results" subdirectory.
023    * </p>
024    * @version
025    *   $Date: 2012-08-04 13:43:22 -0500 (Sat, 04 Aug 2012) $
026    *   $Rev: 104 $
027    *   $Author: croft $
028    * @author
029    *   Yi Dong
030    * @author
031    *   David Wallace Croft
032    ***********************************************************************/
033    public final class  UserSenNeuron
034      implements Neuron, Serializable
035    ////////////////////////////////////////////////////////////////////////
036    ////////////////////////////////////////////////////////////////////////
037    {
038    
039    private static final long  serialVersionUID = 0L;
040    
041    private static final String
042      BINARY_DATA_DIR = "results",
043      TEXT_DATA_DIR = "model";
044    
045    //
046    
047    private boolean  record;
048    
049    //** Neuron axons  */
050    //  public Axon axon;
051
052    /** the seed for this neuron */
053
054    private int currentP;
055    
056    private UserSenNeuronPara para;
057    
058    private String myId;
059    
060    private LinkedList<Double> spikeData;
061
062    public long tHost;
063
064    public double time=0.0;
065
066    ////////////////////////////////////////////////////////////////////////
067    ////////////////////////////////////////////////////////////////////////
068
069    public  UserSenNeuron (
070      final UserSenNeuronPara para,
071      final String            pre,
072      final String            suf,
073      final int               x,
074      final int               y )
075    ////////////////////////////////////////////////////////////////////////
076    {
077      this.para = para;
078      
079      if ( !para.gIni )
080      {
081        try
082        {
083//        org.apache.log4j.BasicConfigurator.configure(
084//          new FileAppender(new SimpleLayout(),"log/customncfile.log"));
085//        String filename = "results/"+para.datafile;
086//        para.ncfile = NetcdfFile.open(filename);
087//        para.gIni = true;
088          
089          this.para.rdata = readRecorderDataFromFile ( para.datafile );
090          
091          para.gIni = true;
092        }
093        catch(Exception a)
094        {
095          try
096          {   
097            FileOutputStream
098              out = new FileOutputStream("log/openerror.txt");
099            
100            PrintStream p = new  PrintStream(out);
101            
102            a.printStackTrace(p);
103            
104            p.close();
105          }
106          catch(Exception ex)
107          {
108            // TODO:  ignore?
109          }
110        }
111
112      }
113      
114      myId = pre + "," + x + "," + y + "," + suf;
115    }
116
117    ////////////////////////////////////////////////////////////////////////
118    ////////////////////////////////////////////////////////////////////////
119
120    @Override
121    public void  setTimeOfNextFire ( final double  arg0 )
122    ////////////////////////////////////////////////////////////////////////
123    {
124      this.time = arg0;
125    }
126
127    @Override
128    public double updateFire()
129    ////////////////////////////////////////////////////////////////////////
130    {
131      if(currentP<spikeData.size())
132      {
133        final double  out = spikeData.get(currentP) - this.time;
134        
135        currentP++;
136        
137        return out;
138      }
139      else
140      {
141        return -1.0;
142      }
143    }
144    
145    @Override
146    public double updateInput(double time, Synapse input)
147    ////////////////////////////////////////////////////////////////////////
148    {
149      throw new RuntimeException("sensory neuron won't recieve inputs");
150    }
151    
152    @Override
153    public double  getTimeOfNextFire ( )
154    ////////////////////////////////////////////////////////////////////////
155    {
156      return -1;
157    }
158
159    /*
160    public Axon getAxon()
161    {
162      return axon;
163    }
164    */
165   
166    @Override
167    public String  toString ( )
168    ////////////////////////////////////////////////////////////////////////
169    {
170      String tmp="User defined Sensory Neuron\n";
171      
172//    tmp=tmp+axon;
173      
174      return tmp;
175    }
176    
177    @Override
178    public boolean isSensory()
179    ////////////////////////////////////////////////////////////////////////
180    {
181      return true;
182    }
183
184    /***********************************************************************
185    * Each sub experiment use the date from subexperiment 0, unless changed
186    * the code by uncommenting the line.
187    ***********************************************************************/
188    @Override
189    public void  init (
190      final int      expid,
191      final int      trialid,
192      final Seed     idum,
193      final Network  net,
194      final int      id )
195    ////////////////////////////////////////////////////////////////////////
196    {
197      this.time=0.0;
198      
199      currentP = 0;
200
201//  if(para.rdata.receiver.containsKey("Exp"+expid+"Tri"+trialid+"/"+myId))
202//  {
203//    spikeData=para.rdata.receiver.get("Exp"+expid+"Tri"+trialid+"/"+myId);
204      
205      //only 1 sub experiment
206      
207      spikeData=para.rdata.receiver.get("Exp"+0+"Tri"+trialid+"/"+myId);
208      
209      if(spikeData!=null)
210      {
211        //throw new RuntimeException(
212        //  "not found it"+"Exp"+expid+"Tri"+trialid+"/"+myId);
213        
214        if(currentP < spikeData.size())
215        {
216          final Slot<FireEvent>  fireEventSlot = net.getFireEventSlot ( );
217          
218          if(net.getClass().getName().equals("cnslab.cnsnetwork.ANetwork"))
219          {
220            fireEventSlot.offer (
221              new AFireEvent (
222                id,
223                this.time = updateFire ( ),
224                net.info.idIndex,
225                ( ( ANetwork ) net).aData.getId ( ( ANetwork ) net ) ) );
226          }
227          else if ( net.getClass ( ).getName ( ).equals (
228            "cnslab.cnsnetwork.Network" ) )
229          {
230            fireEventSlot.offer (
231              new FireEvent ( id, this.time = updateFire ( ) ) );
232          }
233          else
234          {
235            throw new RuntimeException (
236              "Other Network Class doesn't exist" );
237          }
238        }
239      }
240//    }
241    }
242
243    @Override
244    public boolean getRecord()
245    ////////////////////////////////////////////////////////////////////////
246    {
247      return this.record;
248    }
249
250    @Override
251    public void setRecord(boolean record)
252    ////////////////////////////////////////////////////////////////////////
253    {
254      this.record = record;
255    }
256
257    @Override
258    public double getMemV(double currT)
259    ////////////////////////////////////////////////////////////////////////
260    {
261      throw new RuntimeException("no memV for sensory neuron");
262    }
263
264    @Override
265    public double [] getCurr(double currT)
266    ////////////////////////////////////////////////////////////////////////
267    {
268      throw new RuntimeException("no curr for sensory neuron");
269    }
270
271    @Override
272    public long getTHost()
273    ////////////////////////////////////////////////////////////////////////
274    {
275      return tHost;
276    }
277
278    @Override
279    public void setTHost(long id)
280    ////////////////////////////////////////////////////////////////////////
281    {
282      this.tHost=id;
283    }
284    
285    @Override
286    public boolean realFire()
287    ////////////////////////////////////////////////////////////////////////
288    {
289      return true;
290    }
291
292    ////////////////////////////////////////////////////////////////////////
293    // private methods
294    ////////////////////////////////////////////////////////////////////////
295    
296    private static RecorderData  readRecorderDataFromFile (
297      final String  dataFilename )
298      throws ClassNotFoundException, IOException
299    ////////////////////////////////////////////////////////////////////////
300    {
301      if ( dataFilename == null )
302      {
303        throw new IllegalArgumentException ( "null" );
304      }
305      
306      if ( dataFilename.endsWith ( ".txt" ) )
307      {
308        final File  textFile = new File ( TEXT_DATA_DIR, dataFilename );
309        
310        return RecorderDataLib.readRecorderDataFromTextFile ( textFile );
311      }
312      
313      final File  binaryFile = new File ( BINARY_DATA_DIR, dataFilename );
314      
315      return RecorderDataLib.readRecorderDataFromBinaryFile ( binaryFile );
316    }
317
318    ////////////////////////////////////////////////////////////////////////
319    ////////////////////////////////////////////////////////////////////////
320    }