001    package cnslab.cnsnetwork;
002    
003    import java.awt.Color;
004    import java.io.FileOutputStream;
005    import java.io.IOException;
006    import java.io.PrintStream;
007    import java.util.ArrayList;
008    import java.util.Iterator;
009    import java.util.LinkedList;
010    import java.util.Map;
011
012    import org.jfree.chart.*;
013    import org.jfree.chart.plot.*;
014    import org.jfree.data.xy.*;
015    import org.jfree.ui.*;
016    import org.slf4j.Logger;
017    import org.slf4j.LoggerFactory;    
018    import ucar.ma2.*;
019    import ucar.nc2.*;
020
021    /***********************************************************************
022    * Write the recorded data into files.
023    *
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, M.Sc.
032    * @author
033    *   Jeremy Cohen
034    ***********************************************************************/
035    public final class  RecWriter
036    ////////////////////////////////////////////////////////////////////////
037    ////////////////////////////////////////////////////////////////////////
038    {
039    
040    private static final Class<RecWriter>
041      CLASS = RecWriter.class;
042
043    private static final Logger
044      LOGGER = LoggerFactory.getLogger ( CLASS );
045    
046    
047    // The character used to separate terms in variable names.
048    private static final String SEPARATOR = "_";
049    
050    //
051  
052    /** info */
053    public Experiment exp;
054
055    /** XML parser */
056    public SimulatorParser pas;
057
058    /** The recorded info */
059    public Map<String, LinkedList<Double>>  receiver;
060
061    public LinkedList[]  intraReceiver;
062
063    /** don't consider trials */
064    public Map<String, Integer>  multiCounter;
065    
066    /** considering separate trials */
067    public Map<String, Integer>  multiCounterAll; 
068
069    /** different time section, neuron */
070    public Map<String, Integer> fieldCounter; 
071
072    /** different time section, neuron for X axis */
073    public Map<String, Double>  vectorCounterX;
074    
075    /** different time section, neuron for Y axis */
076    public Map<String, Double>  vectorCounterY;
077    
078    public ArrayList<ArrayList<Map<String, Integer>>>  avalancheCounter; 
079
080    ////////////////////////////////////////////////////////////////////////
081    ////////////////////////////////////////////////////////////////////////
082        
083    public  RecWriter (
084      final Experiment       exp,
085      final SimulatorParser  pas,
086      final LinkedList [ ]   intraReceiver,
087      final RecorderData     rdata )
088    ////////////////////////////////////////////////////////////////////////
089    {
090      this.exp = exp;
091      this.pas = pas;
092      this.receiver = rdata.receiver;
093      this.intraReceiver = intraReceiver;
094      this.multiCounter = rdata.multiCounter;
095      this.multiCounterAll =  rdata.multiCounterAll;
096      this.fieldCounter = rdata.fieldCounter;
097      this.vectorCounterX = rdata.vectorCounterX;
098      this.vectorCounterY = rdata.vectorCounterY;
099    }
100
101    public  RecWriter (
102      final Experiment        exp,
103      final SimulatorParser   pas,
104      final LinkedList [ ]    intraReceiver,
105      final RecorderData      rdata,
106      final AvalancheCounter  aData )
107    ////////////////////////////////////////////////////////////////////////
108    {
109      this.exp = exp;
110      this.pas = pas;
111      this.receiver = rdata.receiver;
112      this.intraReceiver = intraReceiver;
113      this.multiCounter = rdata.multiCounter;
114      this.multiCounterAll =  rdata.multiCounterAll;
115      this.fieldCounter = rdata.fieldCounter;
116      this.vectorCounterX = rdata.vectorCounterX;
117      this.vectorCounterY = rdata.vectorCounterY;
118      this.avalancheCounter = aData.avalancheCounter;
119    }
120
121    /***********************************************************************
122    * Record the data into file fileOut
123    *
124    * @param fileOut
125    * 
126    * @throws Exception
127    ***********************************************************************/
128    public void  record ( final String  fileOut )
129      throws Exception
130    ////////////////////////////////////////////////////////////////////////
131    {
132      // Debug
133      FileOutputStream out = new FileOutputStream("log/debug_recwriter.txt");
134      PrintStream p = new  PrintStream(out);
135      p.println("Hello!");
136      p.close();
137      
138      //prepare the recorder's file
139      String filename = "results/"+fileOut;
140      NetcdfFileWriteable ncfile = NetcdfFileWriteable.createNew(filename, false);
141      ArrayList<Dimension> dims;
142      Dimension eleId=null,mulEleId=null,fieldEleId=null,vectorEleId=null,intraEleId=null;
143      Dimension [] vectorX=null,vectorY=null,intraCha=null,fieldX=null,fieldY=null;
144      Dimension sLen = ncfile.addDimension("svarLen", 40); //length of each name is no longer than 40;
145      if(exp.recorder.singleUnit.size()>0)
146      {
147        eleId = ncfile.addDimension("suEleId", exp.recorder.singleUnit.size());
148        dims = new ArrayList<Dimension>();
149        dims.add(eleId);
150        dims.add(sLen);
151        ncfile.addVariable("suNames", DataType.CHAR, dims);
152      }
153
154      if(exp.recorder.multiUnit.size()>0)
155      {
156        mulEleId = ncfile.addDimension("muEleId", exp.recorder.multiUnit.size());
157        ncfile.addVariable("muBinSize", DataType.DOUBLE, new ArrayList());
158        dims = new ArrayList<Dimension>();
159        dims.add(mulEleId);
160        dims.add(sLen);
161        ncfile.addVariable("muNames", DataType.CHAR, dims);
162      }
163
164      if(exp.recorder.fieldNames.size()>0)
165      {
166        fieldEleId = ncfile.addDimension("fieldEleId", exp.recorder.fieldNames.size());
167        fieldX =  new Dimension[exp.recorder.fieldEle.size()];
168        fieldY =  new Dimension[exp.recorder.fieldEle.size()];
169        ncfile.addVariable("fieldBinSize", DataType.DOUBLE, new ArrayList());
170        dims = new ArrayList<Dimension>();
171        dims.add(fieldEleId);
172        dims.add(sLen);
173        ncfile.addVariable("fieldNames", DataType.CHAR, dims);
174      }
175
176      if(exp.recorder.vectorNames.size()>0)
177      {
178        vectorEleId = ncfile.addDimension("vectorEleId", exp.recorder.vectorNames.size());
179        vectorX =  new Dimension[exp.recorder.vectorUnit.size()];
180        vectorY =  new Dimension[exp.recorder.vectorUnit.size()];
181        ncfile.addVariable("vectorBinSize", DataType.DOUBLE, new ArrayList());
182        dims = new ArrayList<Dimension>();
183        dims.add(vectorEleId);
184        dims.add(sLen);
185        ncfile.addVariable("vectorNames", DataType.CHAR, dims);
186      }
187
188      if(exp.recorder.intraNames.size()>0)
189      {
190        intraEleId = ncfile.addDimension("intraEleId", exp.recorder.intraNames.size());
191        intraCha =  new Dimension[exp.recorder.intraEle.size()];
192        ncfile.addVariable("intraBinSize", DataType.DOUBLE, new ArrayList());
193        dims = new ArrayList<Dimension>();
194        dims.add(intraEleId);
195        dims.add(sLen);
196        ncfile.addVariable("intraNames", DataType.CHAR, dims);
197      }
198
199      Dimension trials[] = new Dimension[exp.subExp.length];
200
201      Dimension multiBinLen[] = new Dimension[exp.subExp.length];
202      Dimension fieldBinLen[] = new Dimension[exp.subExp.length];
203      Dimension vectorBinLen[] = new Dimension[exp.subExp.length];
204      Dimension intraBinLen[] = new Dimension[exp.subExp.length];
205
206
207      for(int  i=0; i<exp.recorder.intraEle.size(); i++)
208      {
209        intraCha[i] = ncfile.addDimension("channel"+i, exp.recorder.currChannel.get(i).size());
210      }
211
212
213
214      for(int i=0; i<exp.recorder.fieldEle.size(); i++)
215      {
216        int xMul,yMul;
217        xMul = exp.recorder.fieldEle.get(i).getMultiplierX();
218        yMul = exp.recorder.fieldEle.get(i).getMultiplierY();
219
220        if(xMul < 0 )
221        {
222          if(pas.xEdgeLength % xMul !=0 ) throw new RuntimeException(xMul+"is not a multiplier of x-edge length"+pas.xEdgeLength);
223        }
224        if(yMul < 0 )
225        {
226          if(pas.yEdgeLength % yMul !=0 ) throw new RuntimeException(yMul+"is not a multiplier of y-edge length"+pas.yEdgeLength);
227        }
228
229        fieldX[i] = ncfile.addDimension("fieldX"+i, (xMul >0 ? pas.xEdgeLength*xMul : pas.xEdgeLength/(-xMul)));
230        fieldY[i] = ncfile.addDimension("fieldY"+i, (yMul >0 ? pas.yEdgeLength*yMul : pas.yEdgeLength/(-yMul)));
231//      System.out.println("pas.xEdgeLength "+pas.xEdgeLength+" pas.yEdgeLength "+pas.yEdgeLength+ " xsize "+(xMul >0 ? pas.xEdgeLength*xMul : pas.xEdgeLength/(-xMul))+" ysize "+(yMul >0 ? pas.yEdgeLength*yMul : pas.yEdgeLength/(-yMul))+" xMul "+xMul+" yMul "+yMul);
232      }
233
234      for(int i=0; i<exp.recorder.vectorUnit.size(); i++)
235      {
236        int xMul,yMul;
237        xMul = exp.recorder.vectorUnit.get(i).coms.get(0).layer.getMultiplierX();
238        yMul = exp.recorder.vectorUnit.get(i).coms.get(0).layer.getMultiplierY();
239
240        if(xMul < 0 )
241        {
242          if(pas.xEdgeLength % xMul !=0 ) throw new RuntimeException(xMul+"is not a multiplier of x-edge length"+pas.xEdgeLength);
243        }
244        if(yMul < 0 )
245        {
246          if(pas.yEdgeLength % yMul !=0 ) throw new RuntimeException(yMul+"is not a multiplier of y-edge length"+pas.yEdgeLength);
247        }
248
249        vectorX[i] = ncfile.addDimension("vectorX"+i, (xMul >0 ? pas.xEdgeLength*xMul : pas.xEdgeLength/(-xMul)));
250        vectorY[i] = ncfile.addDimension("vectorY"+i, (yMul >0 ? pas.yEdgeLength*yMul : pas.yEdgeLength/(-yMul)));
251//      System.out.println("pas.xEdgeLength "+pas.xEdgeLength+" pas.yEdgeLength "+pas.yEdgeLength+ " xsize "+(xMul >0 ? pas.xEdgeLength*xMul : pas.xEdgeLength/(-xMul))+" ysize "+(yMul >0 ? pas.yEdgeLength*yMul : pas.yEdgeLength/(-yMul))+" xMul "+xMul+" yMul "+yMul);
252      }
253
254
255      Dimension numSub = ncfile.addDimension("subexpId", exp.subExp.length);
256      ncfile.addVariable("subExpNum", DataType.INT, new ArrayList());
257      ncfile.addVariable("xEdgeLen", DataType.INT, new ArrayList());
258      ncfile.addVariable("yEdgeLen", DataType.INT, new ArrayList());
259
260      
261      dims = new ArrayList<Dimension>();
262      dims.add(numSub);
263      dims.add(sLen);
264      ncfile.addVariable("subexpNames", DataType.CHAR, dims);
265
266
267      for(int expId=0; expId < exp.subExp.length; expId++)
268      {       
269        trials[expId] = ncfile.addDimension("subTrial"+expId, exp.subExp[expId].repetition);
270
271        if(exp.recorder.multiUnit.size()>0)
272        {
273          multiBinLen[expId] = ncfile.addDimension("binLen"+expId, (int)(exp.subExp[expId].trialLength/exp.recorder.timeBinSize));
274        }
275        if(exp.recorder.fieldEle.size()>0)
276        {
277          fieldBinLen[expId] = ncfile.addDimension("fBinLen"+expId, (int)(exp.subExp[expId].trialLength/exp.recorder.fieldTimeBinSize));
278        }
279        if(exp.recorder.vectorUnit.size()>0)
280        {
281          vectorBinLen[expId] = ncfile.addDimension("vBinLen"+expId, (int)(exp.subExp[expId].trialLength/exp.recorder.vectorTimeBinSize));
282        }
283        if(exp.recorder.intraEle.size()>0)
284        {
285          intraBinLen[expId] = ncfile.addDimension("iBinLen"+expId, (int)(exp.subExp[expId].trialLength/exp.recorder.intraTimeBinSize));
286        }
287
288        String subExpPrefix = "SubExp" + expId + SEPARATOR;
289
290        Variable trialNum = ncfile.addVariable(subExpPrefix + "trialNum", DataType.INT, new ArrayList());
291
292        for(int tID=0; tID<exp.subExp[expId].repetition; tID++)
293        {
294          String trialPrefix = subExpPrefix + "trial" + tID + SEPARATOR;
295                
296          Variable ele[] = new Variable[exp.recorder.singleUnit.size()];
297
298          if(avalancheCounter!=null) //record only necessary
299          {
300            Dimension dim_ava = ncfile.addDimension("A_E"+expId+"T"+tID, avalancheCounter.get(expId).get(tID).size());                  
301            dims = new ArrayList<Dimension>();
302            dims.add(dim_ava);
303            Variable avalan = ncfile.addVariable(trialPrefix + "ava" + tID, DataType.INT, dims);
304          }
305
306          for(int sID = 0; sID < exp.recorder.singleUnit.size(); sID++)
307          {       
308            if(receiver.get("E"+expId+"T"+tID+"N"+exp.recorder.singleUnit.get(sID))!=null)
309            {
310              Dimension timeDim = ncfile.addDimension("tE"+expId+"T"+tID+"N"+exp.recorder.singleUnit.get(sID), receiver.get("E"+expId+"T"+tID+"N"+exp.recorder.singleUnit.get(sID)).size());
311              dims = new ArrayList<Dimension>();
312              dims.add(timeDim);
313              ele[sID] = ncfile.addVariable(trialPrefix + exp.recorder.suNames.get(sID), DataType.DOUBLE, dims);
314            }
315          }       
316//          g.addGroup(t);
317
318        } // END: for trial loop
319
320        //multi unit ele
321        for(int mID = 0 ; mID < exp.recorder.multiUnit.size(); mID++)
322        {
323                
324          dims = new ArrayList<Dimension>();
325          dims.add(multiBinLen[expId]);
326          Variable multiEle = ncfile.addVariable(subExpPrefix + exp.recorder.multiNames.get(mID), DataType.DOUBLE, dims); //average over trials and electrodes;
327
328          dims = new ArrayList<Dimension>();
329          dims.add(trials[expId]);
330          dims.add(multiBinLen[expId]);
331          Variable multiEleAll = ncfile.addVariable(subExpPrefix + exp.recorder.multiNames.get(mID) + SEPARATOR + "ALL", DataType.DOUBLE, dims); // average over electrodes put trials as another dimension
332        }
333
334        for(int fID = 0 ; fID < exp.recorder.fieldEle.size(); fID++)
335        {               
336                dims = new ArrayList<Dimension>();
337                dims.add(fieldX[fID]);
338                dims.add(fieldY[fID]);
339                dims.add(fieldBinLen[expId]);
340                Variable fieldEle = ncfile.addVariable(subExpPrefix + exp.recorder.fieldNames.get(fID), DataType.DOUBLE, dims); // average over trials and electrodes
341        }
342
343        for(int vID = 0 ; vID < exp.recorder.vectorUnit.size(); vID++)
344        {
345                dims = new ArrayList<Dimension>();
346                dims.add(vectorX[vID]);
347                dims.add(vectorY[vID]);
348                dims.add(vectorBinLen[expId]);
349                Variable vectorEleX = ncfile.addVariable(subExpPrefix + exp.recorder.vectorNames.get(vID) + SEPARATOR + "X", DataType.DOUBLE, dims);
350                Variable vectorEleY = ncfile.addVariable(subExpPrefix + exp.recorder.vectorNames.get(vID) + SEPARATOR + "Y", DataType.DOUBLE, dims);
351        }
352
353        for(int iID = 0 ; iID < exp.recorder.intraEle.size(); iID++)
354        {               
355                dims = new ArrayList<Dimension>();
356                dims.add(intraBinLen[expId]);
357                // Average over trials and electrodes
358                Variable intraEleV = ncfile.addVariable(subExpPrefix + exp.recorder.intraNames.get(iID) + SEPARATOR + "V", DataType.DOUBLE, dims);
359                
360                dims = new ArrayList<Dimension>();
361                dims.add(intraCha[iID]);
362                dims.add(intraBinLen[expId]);
363                // Average over trials and electrodes
364                Variable intraEleC = ncfile.addVariable(subExpPrefix + exp.recorder.intraNames.get(iID) + SEPARATOR + "C", DataType.DOUBLE, dims);
365        }
366
367      }
368      ncfile.create();
369      //end of preparation
370
371
372      //recording...now
373
374      ArrayInt.D0 datas = new ArrayInt.D0();
375      datas.set(exp.subExp.length);
376      ncfile.write("subExpNum", datas);
377
378      ArrayChar ac2;
379      ArrayDouble.D0 binSize;
380
381      if(exp.recorder.multiUnit.size()>0)
382      {
383        binSize = new ArrayDouble.D0();
384        binSize.set(exp.recorder.timeBinSize);
385        ncfile.write("muBinSize", binSize);
386        ac2 = new ArrayChar.D2(exp.recorder.multiUnit.size(), 40);
387        for( int sID= 0; sID < exp.recorder.multiUnit.size(); sID++) 
388        {
389          ac2.setString(sID,exp.recorder.multiNames.get(sID));
390        }
391        ncfile.write("muNames", ac2);
392      }
393
394      if(exp.recorder.fieldNames.size()>0)
395      {
396
397        binSize = new ArrayDouble.D0();
398        binSize.set(exp.recorder.fieldTimeBinSize);
399        ncfile.write("fieldBinSize", binSize);
400
401        ac2 = new ArrayChar.D2(exp.recorder.fieldNames.size(), 40);
402        for( int sID= 0; sID < exp.recorder.fieldNames.size(); sID++) 
403        {
404          ac2.setString(sID,exp.recorder.fieldNames.get(sID));
405        }
406        ncfile.write("fieldNames", ac2);
407      }
408
409      if(exp.recorder.vectorNames.size()>0)
410      {
411        binSize = new ArrayDouble.D0();
412        binSize.set(exp.recorder.vectorTimeBinSize);
413        ncfile.write("vectorBinSize", binSize);
414        ac2 = new ArrayChar.D2(exp.recorder.vectorNames.size(), 40);
415        for( int sID= 0; sID < exp.recorder.vectorNames.size(); sID++) 
416        {
417          ac2.setString(sID,exp.recorder.vectorNames.get(sID));
418        }
419        ncfile.write("vectorNames", ac2);
420      }
421
422      if(exp.recorder.intraNames.size()>0)
423      {
424        binSize = new ArrayDouble.D0();
425        binSize.set(exp.recorder.intraTimeBinSize);
426        ncfile.write("intraBinSize", binSize);
427        ac2 = new ArrayChar.D2(exp.recorder.intraNames.size(), 40);
428        for( int sID= 0; sID < exp.recorder.intraNames.size(); sID++) 
429        {
430          ac2.setString(sID,exp.recorder.intraNames.get(sID));
431        }
432        ncfile.write("intraNames", ac2);
433
434      }
435
436      datas = new ArrayInt.D0();
437      datas.set(pas.xEdgeLength );
438      ncfile.write("xEdgeLen", datas);
439
440      datas = new ArrayInt.D0();
441      datas.set(pas.yEdgeLength);
442      ncfile.write("yEdgeLen", datas);
443
444
445
446
447
448      ac2 = new ArrayChar.D2(exp.recorder.singleUnit.size(), 40);
449
450      if(exp.recorder.singleUnit.size()>0)
451      {
452
453        for( int sID= 0; sID < exp.recorder.singleUnit.size(); sID++) 
454        {
455          ac2.setString(sID,exp.recorder.suNames.get(sID));
456        }
457        ncfile.write("suNames", ac2);
458      }
459
460
461
462      ac2 = new ArrayChar.D2(exp.subExp.length, 40);
463      for( int sID= 0; sID < exp.subExp.length; sID++) 
464      {
465        ac2.setString(sID,exp.subExp[sID].name);
466      }
467      ncfile.write("subexpNames", ac2);
468
469
470
471
472      for(int expId=0; expId < exp.subExp.length; expId++)
473      {       
474        ArrayDouble.D0 dtrial = new ArrayDouble.D0();
475        dtrial.set(exp.subExp[expId].repetition);
476        ncfile.write("SubExp" + expId + SEPARATOR + "trialNum", dtrial);
477
478        for(int tID=0; tID<exp.subExp[expId].repetition; tID++)
479        {
480//      Map<String, Integer> mapdata = avalancheCounter.get(expId).get(tID);
481          if(avalancheCounter!=null) //record when it is necessary
482          {
483            ArrayInt.D1 ava_input =  new ArrayInt.D1(avalancheCounter.get(expId).get(tID).size());  
484            Iterator<Integer> values = avalancheCounter.get(expId).get(tID).values().iterator();
485            int i_counter=0;
486            while(values.hasNext())
487            {
488              ava_input.set(i_counter++, values.next());
489            }
490            int [] ava_origin = new int [] {0};
491            ncfile.write("SubExp" + expId + SEPARATOR + "trial" + tID + SEPARATOR + "ava" + tID, ava_origin, ava_input);
492
493          }
494          //single unit
495          for( int sID= 0; sID < exp.recorder.singleUnit.size(); sID++) 
496          {
497            LinkedList<Double> tmp = receiver.get("E"+expId+"T"+tID+"N"+exp.recorder.singleUnit.get(sID));
498//        System.out.println("E"+expId+"T"+tID+"N"+exp.rec.singleUnit.get(sID));
499            if(tmp!=null)
500            {
501              ArrayDouble.D1 input = new ArrayDouble.D1(tmp.size());
502              //Index ima = input.getIndex();
503
504              //double[] tmpDouble= new double[tmp.size()];
505              //System.out.println("size"+tmp.size());
506              int ii =0;
507              for(double val : tmp)
508              {
509                input.set(ii++,val);
510                //tmpDouble[ii++]= val;
511              }
512
513              int [] origin = new int [] {0};
514              ncfile.write("SubExp" + expId + SEPARATOR + "trial" + tID + SEPARATOR + exp.recorder.suNames.get(sID), origin, input);
515            }
516          }
517/*
518      //multi unit
519      for(int mID = 0 ; mID < exp.rec.multiUnit.size(); mID++)
520      {
521        for(int eID =0 ; eID < exp.rec.multiUnit.get(mID).size(); eID++)
522        {
523          LinkedList<Double> tmp = receiver.get("E"+expId+"T"+tID+"N"+exp.rec.multiUnit.get(mID).get(eID));
524          if(tmp!=null)
525          {
526            for( double val : tmp)
527            {
528              int binIndex = (int)(val/exp.rec.timeBinSize);
529              Integer tmpInt = multiCounter.get("E"+expId+"N"+mID+"B"+binIndex);
530              if(tmpInt == null)
531              {
532                multiCounter.put("E"+expId+"N"+mID+"B"+binIndex, tmpInt=(new Integer(0)));
533              }
534              tmpInt = tmpInt + 1;
535              multiCounter.put("E"+expId+"N"+mID+"B"+binIndex, tmpInt);
536
537              Integer tmpIntAll = multiCounterAll.get("E"+expId+"T"+tID+"N"+mID+"B"+binIndex);
538              if(tmpIntAll == null)
539              {
540                multiCounterAll.put("E"+expId+"T"+tID+"N"+mID+"B"+binIndex, tmpIntAll=(new Integer(0)));
541              }
542              tmpIntAll = tmpIntAll + 1;
543              multiCounterAll.put("E"+expId+"T"+tID+"N"+mID+"B"+binIndex, tmpIntAll);
544
545            }
546
547          }
548        }
549      }
550
551      //field electrode
552      for(int fID = 0 ; fID < exp.rec.fieldEle.size(); fID++)
553      {
554        int xMul,yMul;
555        xMul = exp.rec.fieldEle.get(fID).getXmultiplier();
556        yMul = exp.rec.fieldEle.get(fID).getYmultiplier();
557        String pre = exp.rec.fieldEle.get(fID).getPrefix();
558        String suf = exp.rec.fieldEle.get(fID).getSuffix();
559
560
561
562        int xstep,ystep;
563        int xresosize,yresosize;
564
565        if(xMul>0)
566        {
567          xstep=1;
568          xresosize=xMul*pas.xEdgeLength;
569        }
570        else
571        {
572          xstep=-xMul;
573          xresosize=pas.xEdgeLength;
574        }
575        if(yMul>0)
576        {
577          ystep=1;
578          yresosize=yMul*pas.yEdgeLength;
579        }
580        else
581        {
582          ystep=-yMul;
583          yresosize=pas.yEdgeLength;
584        }
585
586        for(int xx=0 ; xx < xresosize; xx+=xstep)
587        {
588          for(int yy=0; yy< yresosize; yy+=ystep)
589          {
590            // LinkedList<Double> tmp = receiver.get("E"+expId+"T"+tID+"N"+pas.ls.cellmap.get(pre+","+xx+","+yy+","+suf));
591             LinkedList<Double> tmp = receiver.get("E"+expId+"T"+tID+"N"+pas.ls.cellmap_slow(pre,suf,xx,yy));
592
593
594            if(tmp!=null)
595            {
596              for( double val : tmp)
597              {
598                int binIndex = (int)(val/exp.rec.fieldTimeBinSize);
599                Integer tmpInt = fieldCounter.get("E"+expId+","+pre+","+xx+","+yy+","+suf+","+"B"+binIndex);
600                if(tmpInt == null)
601                {
602                  fieldCounter.put("E"+expId+","+pre+","+xx+","+yy+","+suf+","+"B"+binIndex, tmpInt=(new Integer(0)));
603                }
604                tmpInt = tmpInt + 1;
605                fieldCounter.put("E"+expId+","+pre+","+xx+","+yy+","+suf+","+"B"+binIndex, tmpInt);
606              }
607            }
608          }
609        }
610
611      }
612
613      //vector electrode
614      for(int vID = 0 ; vID < exp.rec.vectorUnit.size(); vID++)
615      {
616        for(int cID =0 ; cID < exp.rec.vectorUnit.get(vID).coms.size(); cID++)
617        {
618          int xMul,yMul;
619          xMul = exp.rec.vectorUnit.get(vID).coms.get(cID).layer.getXmultiplier();
620          yMul = exp.rec.vectorUnit.get(vID).coms.get(cID).layer.getYmultiplier();
621          String pre = exp.rec.vectorUnit.get(vID).coms.get(cID).layer.getPrefix();
622          String suf = exp.rec.vectorUnit.get(vID).coms.get(cID).layer.getSuffix();
623
624          int xstep,ystep;
625          int xresosize,yresosize;
626
627          if(xMul>0)
628          {
629            xstep=1;
630            xresosize=xMul*pas.xEdgeLength;
631          }
632          else
633          {
634            xstep=-xMul;
635            xresosize=pas.xEdgeLength;
636          }
637          if(yMul>0)
638          {
639            ystep=1;
640            yresosize=yMul*pas.yEdgeLength;
641          }
642          else
643          {
644            ystep=-yMul;
645            yresosize=pas.yEdgeLength;
646          }
647
648          for(int xx=0 ; xx < xresosize; xx+=xstep)
649          {
650            for(int yy=0; yy< yresosize; yy+=ystep)
651            {
652            //  LinkedList<Double> tmp = receiver.get("E"+expId+"T"+tID+"N"+pas.ls.cellmap.get(pre+","+xx+","+yy+","+suf));
653              LinkedList<Double> tmp = receiver.get("E"+expId+"T"+tID+"N"+pas.ls.cellmap_slow(pre,suf,xx,yy));
654
655
656              if(tmp!=null)
657              {
658                for( double val : tmp)
659                {
660                  int binIndex = (int)(val/exp.rec.vectorTimeBinSize);
661                  Double tmpDX = vectorCounterX.get("E"+expId+"V"+vID+"B"+binIndex+"C"+xx+","+yy);
662                  Double tmpDY = vectorCounterY.get("E"+expId+"V"+vID+"B"+binIndex+"C"+xx+","+yy);
663
664                  if(tmpDX == null)
665                  {
666                    vectorCounterX.put("E"+expId+"V"+vID+"B"+binIndex+"C"+xx+","+yy, tmpDX=(new Double(0.0)));
667                    vectorCounterY.put("E"+expId+"V"+vID+"B"+binIndex+"C"+xx+","+yy, tmpDY=(new Double(0.0)));
668                  }
669
670                  tmpDX = tmpDX + Math.cos( Math.PI/180.0*(double)exp.rec.vectorUnit.get(vID).coms.get(cID).orientation);
671                  tmpDY = tmpDY + Math.sin( Math.PI/180.0*(double)exp.rec.vectorUnit.get(vID).coms.get(cID).orientation);
672                  vectorCounterX.put("E"+expId+"V"+vID+"B"+binIndex+"C"+xx+","+yy, tmpDX);
673                  vectorCounterY.put("E"+expId+"V"+vID+"B"+binIndex+"C"+xx+","+yy, tmpDY);
674                }
675              }
676            }
677          }
678
679        }
680      }
681 */
682
683        } // END: for all trials in a subexp
684        
685        recordMultiUnit (
686          exp,
687          expId,
688          multiCounter,
689          multiCounterAll,
690          ncfile );
691
692        //recorder for the field ele
693        for(int fID = 0 ; fID < exp.recorder.fieldEle.size(); fID++)
694        {
695          int xMul,yMul;
696          xMul = exp.recorder.fieldEle.get(fID).getMultiplierX();
697          yMul = exp.recorder.fieldEle.get(fID).getMultiplierY();
698          String pre = exp.recorder.fieldEle.get(fID).getPrefix();
699          String suf = exp.recorder.fieldEle.get(fID).getSuffix();
700
701          int xstep,ystep;
702          int xresosize,yresosize;
703
704          if(xMul>0)
705          {
706            xstep=1;
707            xresosize=xMul*pas.xEdgeLength;
708          }
709          else
710          {
711            xstep=-xMul;
712            xresosize=pas.xEdgeLength;
713          }
714          if(yMul>0)
715          {
716            ystep=1;
717            yresosize=yMul*pas.yEdgeLength;
718          }
719          else
720          {
721            ystep=-yMul;
722            yresosize=pas.yEdgeLength;
723          }
724
725          ArrayDouble.D3 input = new ArrayDouble.D3(xresosize/xstep,yresosize/ystep, (int)(exp.subExp[expId].trialLength/exp.recorder.fieldTimeBinSize));
726          for(int xx=0 ; xx < xresosize; xx+=xstep)
727          {
728            for(int yy=0; yy< yresosize; yy+=ystep)
729            {
730              for( int ii = 0 ; ii < (int)(exp.subExp[expId].trialLength/exp.recorder.fieldTimeBinSize) ; ii++)
731              {
732
733                Integer outInt=fieldCounter.get("E"+expId+","+pre+","+xx+","+yy+","+suf+","+"B"+ii);
734                if(outInt==null) outInt= new Integer(0);
735                input.set(xx/xstep,yy/ystep,ii,(double)outInt/(double)(exp.subExp[expId].repetition));
736              }
737            }
738          }
739          int [] origin = new int [] {0,0,0};
740        ncfile.write("SubExp" + expId + SEPARATOR + exp.recorder.fieldNames.get(fID), origin, input);
741
742        }
743        
744        //recorder for the vector ele
745        for(int vID = 0 ; vID < exp.recorder.vectorUnit.size(); vID++)
746        {
747          int xMul,yMul;
748          xMul = exp.recorder.vectorUnit.get(vID).coms.get(0).layer.getMultiplierX();
749          yMul = exp.recorder.vectorUnit.get(vID).coms.get(0).layer.getMultiplierY();
750          String pre = exp.recorder.vectorUnit.get(vID).coms.get(0).layer.getPrefix();
751          String suf = exp.recorder.vectorUnit.get(vID).coms.get(0).layer.getSuffix();
752          int xstep,ystep;
753          int xresosize,yresosize;
754
755          if(xMul>0)
756          {
757            xstep=1;
758            xresosize=xMul*pas.xEdgeLength;
759          }
760          else
761          {
762            xstep=-xMul;
763            xresosize=pas.xEdgeLength;
764          }
765          if(yMul>0)
766          {
767            ystep=1;
768            yresosize=yMul*pas.yEdgeLength;
769          }
770          else
771          {
772            ystep=-yMul;
773            yresosize=pas.yEdgeLength;
774          }
775
776          ArrayDouble.D3 inputX = new ArrayDouble.D3(xresosize/xstep,yresosize/ystep, (int)(exp.subExp[expId].trialLength/exp.recorder.vectorTimeBinSize));
777          ArrayDouble.D3 inputY = new ArrayDouble.D3(xresosize/xstep,yresosize/ystep, (int)(exp.subExp[expId].trialLength/exp.recorder.vectorTimeBinSize));
778
779          for(int xx=0 ; xx < xresosize; xx+=xstep)
780          {
781            for(int yy=0; yy< yresosize; yy+=ystep)
782            {
783              for( int ii = 0 ; ii < (int)(exp.subExp[expId].trialLength/exp.recorder.vectorTimeBinSize) ; ii++)
784              {
785
786                Double outDX = vectorCounterX.get("E"+expId+"V"+vID+"B"+ii+"C"+xx+","+yy);
787                Double outDY = vectorCounterY.get("E"+expId+"V"+vID+"B"+ii+"C"+xx+","+yy);
788                if(outDX==null) outDX= new Double(0.0);
789                if(outDY==null) outDY= new Double(0.0);
790                inputX.set(xx/xstep,yy/ystep,ii,(double)outDX/(double)(exp.subExp[expId].repetition));
791                inputY.set(xx/xstep,yy/ystep,ii,(double)outDY/(double)(exp.subExp[expId].repetition));
792              }
793            }
794          }
795          int [] origin = new int [] {0,0,0};
796          ncfile.write("SubExp" + expId + SEPARATOR + exp.recorder.vectorNames.get(vID) + SEPARATOR + "X", origin, inputX);
797          ncfile.write("SubExp" + expId + SEPARATOR + exp.recorder.vectorNames.get(vID) + SEPARATOR + "Y", origin, inputY);
798        }
799
800        //recorder for the intra ele
801        for(int iID = 0 ; iID < exp.recorder.intraEle.size(); iID++)
802        {
803//      System.out.println("exp.subExp[expId].trialLength"+ exp.subExp[expId].trialLength);
804//      System.out.println("exp.rec.intraTimeBinSize" + exp.rec.intraTimeBinSize );
805          ArrayDouble.D1 inputV = new ArrayDouble.D1((int)(exp.subExp[expId].trialLength/exp.recorder.intraTimeBinSize));
806          ArrayDouble.D2 inputC = new ArrayDouble.D2( exp.recorder.currChannel.get(iID).size(), (int)(exp.subExp[expId].trialLength/exp.recorder.intraTimeBinSize));
807
808          LinkedList<IntraInfo> currList = (LinkedList<IntraInfo>)intraReceiver[iID+expId*exp.recorder.intraEle.size()];
809          Iterator<IntraInfo> intraData = currList.iterator();
810
811          for(int xx=0 ; xx < (int)(exp.subExp[expId].trialLength/exp.recorder.intraTimeBinSize); xx++)
812          {
813            IntraInfo tmp = intraData.next();
814
815            inputV.set(xx, tmp.memV);
816
817            for(int yy=0 ; yy < exp.recorder.currChannel.get(iID).size(); yy++)
818            {
819              inputC.set(yy, xx, tmp.curr.get(yy));
820            }
821          }
822
823          int [] origin = new int [] {0};
824          ncfile.write("SubExp" + expId + SEPARATOR + exp.recorder.intraNames.get(iID) + SEPARATOR + "V", origin, inputV);
825          
826          origin = new int [] {0,0};
827          ncfile.write("SubExp" + expId + SEPARATOR + exp.recorder.intraNames.get(iID) + SEPARATOR + "C", origin, inputC);
828        }
829
830      } // END: for subexp loop
831//    receiver.clear();
832      ncfile.close();
833    }
834
835    public void  plot ( )
836    ////////////////////////////////////////////////////////////////////////
837    {
838      for(int expId=0; expId < exp.subExp.length; expId++)
839      {       
840
841        XYSeries xyseries[]= new XYSeries[exp.recorder.singleUnit.size()];
842
843        XYSeriesCollection xyseriescollection = new XYSeriesCollection();
844        for(int tID=0; tID<exp.subExp[expId].repetition; tID++)
845        {
846
847
848          //single unit
849          for( int sID= 0; sID < exp.recorder.singleUnit.size(); sID++) 
850          {
851            LinkedList<Double> tmp = receiver.get("E"+expId+"T"+tID+"N"+exp.recorder.singleUnit.get(sID));
852            if(tmp!=null)
853            {
854              int ii =0;
855              for(double val : tmp)
856              {
857                if(xyseries[sID] == null) xyseries[sID] = new XYSeries(exp.recorder.suNames.get(sID));
858                xyseries[sID].add(val,1.0/(double)exp.recorder.singleUnit.size()*(double)sID+(double)tID);
859
860              }
861
862            }
863          }
864
865        } // END: for all trials in a subexp
866        for(int sID= 0; sID < exp.recorder.singleUnit.size(); sID++)
867        {
868          xyseriescollection.addSeries(xyseries[sID]);
869        }
870
871        JFreeChart jfreechart = ChartFactory.createScatterPlot("Subexp"+expId+" Raster Plot","time","Trials",xyseriescollection, PlotOrientation.VERTICAL, true,false,false);
872        XYPlot xyplot = (XYPlot) jfreechart.getPlot();
873        xyplot.setNoDataMessage("NO DATA");
874        xyplot.setRangeZeroBaselineVisible(true);
875        xyplot.setDomainTickBandPaint(new Color(0, 100, 0, 50));
876        xyplot.setRangeTickBandPaint(new Color(0, 100, 0, 50));
877        ChartPanel chartpanel = new ChartPanel(jfreechart);
878        chartpanel.setPreferredSize(new java.awt.Dimension(500, 270));
879        ApplicationFrame appFram =  new ApplicationFrame("Result");
880        appFram.setContentPane(chartpanel);
881        appFram.pack();
882        RefineryUtilities.centerFrameOnScreen(appFram);
883        appFram.setVisible(true);
884      }
885    }
886    
887    ////////////////////////////////////////////////////////////////////////
888    // private methods
889    ////////////////////////////////////////////////////////////////////////
890    
891    private static void  recordMultiUnit (
892      final Experiment            exp,
893      final int                   expId,
894      final Map<String, Integer>  multiCounter,
895      final Map<String, Integer>  multiCounterAll,
896      final NetcdfFileWriteable   ncfile )
897      throws InvalidRangeException, IOException
898    ////////////////////////////////////////////////////////////////////////
899    {
900      // LOGGER.trace ( "recordMultiUnit entered" );
901      
902      final int  binCount = ( int )
903        ( exp.subExp [ expId ].trialLength / exp.recorder.timeBinSize );
904      
905      // LOGGER.trace ( "binCount {}", binCount );
906      
907      final ArrayList<ArrayList<Integer>>
908        multiUnit = exp.recorder.multiUnit;
909      
910      final int  multiUnitCount = multiUnit.size ( );
911    
912      for ( int  mID = 0; mID < multiUnitCount; mID++ )
913      {
914        final ArrayDouble.D1  input = new ArrayDouble.D1 ( binCount );
915        
916        for ( int  ii = 0; ii < binCount; ii++ )
917        {
918          final String  key = "E" + expId + "N" + mID + "B" + ii;
919          
920          Integer  outInt = multiCounter.get ( key );
921          
922          if ( outInt == null )
923          {
924            outInt = new Integer ( 0 );
925          }
926
927          input.set (
928            ii,
929            ( double ) outInt
930              / ( double ) ( exp.subExp [ expId ].repetition )
931              / ( double )
932                ( exp.recorder.multiUnit.get ( mID ).size ( ) ) );
933        }
934        
935        final int [ ]  origin = new int [ ] { 0 };
936        
937        ncfile.write("SubExp" + expId + SEPARATOR + exp.recorder.multiNames.get(mID), origin, input);
938
939        final ArrayDouble.D2  input2 = new ArrayDouble.D2 (
940          exp.subExp[expId].repetition,
941          binCount );
942        
943        for ( int  tID = 0; tID < exp.subExp [ expId ].repetition; tID++ )
944        {
945          for ( int  ii = 0; ii < binCount; ii++ )
946          {
947            final String
948              key = "E" + expId + "T" + tID + "N" + mID + "B" + ii;
949            
950            Integer  outInt = multiCounterAll.get ( key );
951            
952            if ( outInt == null )
953            {
954              outInt = new Integer ( 0 );
955            }
956
957            input2.set (
958              tID,
959              ii,
960              ( double ) outInt / ( double )
961                ( exp.recorder.multiUnit.get ( mID ).size ( ) ) );
962          }
963        }
964        
965        final int [ ]  origin2 = new int [ ] { 0, 0 };
966    
967        ncfile.write("SubExp" + expId + SEPARATOR + exp.recorder.multiNames.get(mID) + SEPARATOR + "ALL", origin2, input2);
968      }
969      
970      // LOGGER.trace ( "recordMultiUnit exiting" );      
971    }
972    
973    ////////////////////////////////////////////////////////////////////////
974    ////////////////////////////////////////////////////////////////////////
975    }
976