how to read in a text file in a plugin

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

how to read in a text file in a plugin

Xiaoyan Ma-2
I am new to write plugins. Could someone here help me how to read in a text file( saved data) into a plugin. It seems I could use getNumber(). But don't know how?


Thanks. Max
Reply | Threaded
Open this post in threaded view
|

Re: how to read in a text file in a plugin

Robert Dougherty
Max,

Your question has several different answers depending on the nature of the
text data, what you need to do with it, and what style of programming you
prefer.  One of the lower-level approaches is illustrated below.  If you
have a text image, you might be able just use
  IJ.run("Text Image... ", "open=D:\\filename.txt");

Bob


Robert P. Dougherty, Ph.D.
President, OptiNav, Inc.
Phone (425) 467-1118
Fax (425) 467-1119
www.optinav.com


import ij.*;
import ij.gui.*;
import ij.plugin.PlugIn;
import java.awt.*;
import java.io.*;
import java.util.*;;

public class Data_Reader implements PlugIn {
        public void run(String arg) {
                float[][] data = readSpaceDelimNumbers("Read data file");
                IJ.write(data.length+" lines of data read.");
        }
        public float[][] readSpaceDelimNumbers(String prompt) {
                Frame fram = new Frame();
                String dialogPrompt = new String("Space delimted numerical
file");
                if (prompt != null){
                        dialogPrompt = prompt;
                }
                FileDialog fd = new
FileDialog(fram,dialogPrompt,FileDialog.LOAD);
                fd.setVisible(true);
                String path = fd.getDirectory();
                String filename = fd.getFile();
                if ((path == null) || (filename == null)) {
                        return null;
                }
                Vector list = new Vector(0, 16);
                try {
                        FileReader fr = new FileReader(path + filename);
                        BufferedReader br = new BufferedReader(fr);
                        String line;
                        list = new Vector(0, 16);

                        do {
                                line = br.readLine();
                                if (line != null){
                                        StringTokenizer st = new
StringTokenizer(line);
                                        if(st.hasMoreTokens())
                                                list.addElement(st);
                                }
                        } while (line != null);
                        fr.close();
                } catch (FileNotFoundException e) {
                        IJ.error("File not found exception");
                } catch (IOException e) {
                        IJ.error("IOException exception");
                }
                int n = list.size();
                float[][] data = new float[n][];
                for (int i = 0; i < n; i++){
                        StringTokenizer st =
(StringTokenizer)list.elementAt(i);
                        int nd = st.countTokens();
                        data[i] = new float[nd];
                        for (int j = 0; j < nd; j++){
                                String part = st.nextToken();
                                try {
                                        //data[i][j] =
Double.valueOf(part).floatValue();
                                        data[i][j] =
Float.valueOf(part).floatValue();
                                }
                                catch (NumberFormatException e) {
                                }
                        }
                }
                return data;
        }
}
 

> -----Original Message-----
> From: ImageJ Interest Group [mailto:[hidden email]] On Behalf Of
> Xiaoyan Ma
> Sent: Saturday, October 08, 2005 11:19 AM
> To: [hidden email]
> Subject: how to read in a text file in a plugin
>
> I am new to write plugins. Could someone here help me how to read in a
> text file( saved data) into a plugin. It seems I could use getNumber().
> But don't know how?
>
>
> Thanks. Max
Reply | Threaded
Open this post in threaded view
|

Re: how to read in a text file in a plugin

Eric Janiaud
In reply to this post by Xiaoyan Ma-2
Hi Max,

I had the same problem, but I could not found the appropriate methods  
in the ImageJ classes.
The big problem is to convert the Strings or characters read into  
numbers that you can manipulate.
So I write my own code.
It is a  java class  (text2Double.java) that read a tab delimited file  
containing numbers, and converting them in an Double[][]. It is not  
specific to ImageJ, so you can use it for any java application.
It uses a Stream Tokenizer to pearse string and translate into double.

I  also included an imageJ plugin (Read_tabDelemited.java) to show you  
how to use it and a test file. The files to be read must be number  
separated by tabulation.

To install it, you must create 3 new files ( Read_tabDelemited.java ,  
Text2double.java and test.txt) by copy and paste the source included at  
the end of this mail, save them in the plugins folder of your ImageJ  
applications and choose compile and run from the plugins menu (chose to  
compile Read_tabDelemited.java ).

If you have a problem, I can send you those file and a compilled  
version off list, by attached documents.

My plugin it not perfect but works fine for my purpose. If you improve  
it by anymeans, I would be pleased to have a feedback.
I hope it will help you.

Eric
--
Dr. Eric Janiaud
School of Physics
Trinity College Dublin
College Green
Dublin 2
Ireland

NEW : Phone: 00353 - 1 - 608 8453
Fax:   00353 - 1 - 671 1759

The  imageJ plugin:  Read_tabDelemited.java :

------------------------------------------------------------------------
-

import ij.*; //to use log()
import ij.io.OpenDialog;
import ij.io.DirectoryChooser;
import ij.plugin.PlugIn; // for PlugIn class
import java.io.File;

/**
  *Plugin illustrating the use of the class Text2double.
  * This class read a tab delimeted txt file containing number.
  * To retrieve the value, use the getTab() method.
  *
  * @author Eric Janiaud
  *  [hidden email]
  *
  */


        public class Read_tabDelemited implements PlugIn {
       
        String inputPath;
        String choosenFile;
       
/**
* Get the name of the file to be read.
*/
        public void Dialogue(){

                OpenDialog od = new OpenDialog("Select a file", "");
                if (od.getFileName()==null) return;
                inputPath = od.getDirectory();
                choosenFile = od.getFileName();
        }
       

       
        public void run(String argv){
                       
                        Dialogue(); //get the name of the file to read
                        File aFile = new File(inputPath + choosenFile); // creates an  
instance of the file class wich point the given file name
                        Text2double t2f = new Text2double(); //creates a Text2double()
                        t2f.loadTabular(aFile); //read the contents of the file and  
store it.
                        int lines = t2f.getLines();
                        int col = t2f.getWidth();
                        IJ.log(inputPath + choosenFile);
                        IJ.log("lines=" +lines+", col="+col );
                        for (int i = 0; i <  lines; i++){
                                for (int j = 0; j<col; j++ ){
// retrieve value and print them on the log:
                                        IJ.log("i=" + i +", j=" + j + ", read value ="+ t2f.getTab(i,j));
                                }
                        }
                }
}


------------------------------------------------------------------------
-
the java class Text2double.java :


-----------------------------------------
/**
@author Eric Janiaud
  *  [hidden email]
Opens a tab-delimeted text file an array of double array
Uses the StreamTokenizer to convert a text file into double / double  
array
Read now also scientific notation: 5.2E2= 5.2*100.
Attention check if 5.2e2 works also!
*/

/**
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StreamTokenizer;
*/
//import ij.IJ;

import java.io.*;
import ij.IJ;

public class Text2double {
  private int numbers, words, chars, lines , width;
  //   String directory, name, path;

  private double[][] tab;
  private boolean initialise;

   Text2double(){
        numbers = 0;
        words = 0;
        chars = 0;
        lines = 0;
        width = 1;
        initialise = false;
   }


        /**  return the value width (nb col) of the loaded tab*/
     public int getWidth() {
         return width;
     }
       
        /**  return the value lines (nb line) of the loaded tab*/
         public int getLines() {
         return lines;
     }
        /**  return the double loaded at the position i j*/
         public double getTab(int i, int j) {
                return tab[i][j];
     }

        /**  print the tab contents*/
        public void afficheTab(){
                for (int i = 0; i < tab.length ; i++){
                                for (int j = 0; j< tab[i].length; j++){
                                sortie(  tab[i][j] + "\t");
                        }
                        sortie( "\n");
                }
        }
       
               
         /** Opens the specified object file (text tab kind) and fill a double  
Array double[][]. */
     public void loadTabular(File theFile){
     
                this.Init();
                try {
             Reader r = new BufferedReader(new FileReader(theFile));
             this.countLinesNb(r);
             r.close();
             r = new BufferedReader(new FileReader(theFile));
             this.remplitTab(r);
                        r.close();
                }
         catch (IOException e) {
             String msg = e.getMessage();
             if (msg==null || msg.equals(""))
                 msg = ""+e;
// sortie("Text2double: " + msg);
         }
     }

       
/**
                ***********************************
                *   Here is the private methodes  *
                ***********************************
*/
       
       
        private void Init(){
                numbers = words = chars = lines = 0;
     }

       
/** Compte les nombres dans le Stream pour definir la taille*/
    private void countLinesNb(Reader r) throws IOException {
         StreamTokenizer tok = new StreamTokenizer(r);
         int numbersPerLine=0, numbersInPreviousLine=0;

         tok.resetSyntax();
         tok.wordChars(33, 255);
         tok.whitespaceChars(0, ' ');
         tok.eolIsSignificant(true);
                tok.slashStarComments(true);
                tok.parseNumbers();
                boolean wasNumber = false;


         while (tok.nextToken() != StreamTokenizer.TT_EOF) {
      boolean isScientific = true;
             switch (tok.ttype) {
                 case StreamTokenizer.TT_EOL: //when end of line
                     lines++;
                     if (numbersPerLine==0){lines--;} // ignore empty  
lines
                     if (lines==1) {width = numbersPerLine;}
                     else if (numbersPerLine!=0 &&  
numbersPerLine!=numbersInPreviousLine)
                          throw new IOException("Line "+lines+ " is not  
the same length as the first line.");
                     if (numbersPerLine!=0){numbersInPreviousLine =  
numbersPerLine;}
                     numbersPerLine = 0;
                     wasNumber = false;
                     break;
                                       
                 case StreamTokenizer.TT_NUMBER: // when number
                                        numbers++; // found another nb
                      numbersPerLine++; // found another nb on the  
line
                                        wasNumber = true;
                      break;
                     
                                case StreamTokenizer.TT_WORD:
        //checking if scientific notation
                                        if ( (tok.sval.startsWith("E")) && (tok.sval.length() > 1) ){
                                                String  expoStr = tok.sval.split("E")[1];
                                                try{double expo = Float.parseFloat(expoStr);}
                                                catch(NumberFormatException e){
                                                        String msg = e.getMessage();
                                                        isScientific = false;
                                                }
// there is a word in the middle of a line (not a title)
                                        }else{isScientific = false;}
                                        if((numbersPerLine != 0) && ( ! isScientific)){
                                                        throw new IOException( " line "+lines+ " contains the string "  
+tok.sval +" AND number." +"\n");
                                                }
                                        break;
             }
         }
                if(tok.ttype == StreamTokenizer.TT_EOF ){   //when end of file (the  
last eol can be replaced by an eof)
                        lines++;
                        if (numbersPerLine==0){lines--;} // ignore empty lines
                        if (lines==1) {width = numbersPerLine;}
                        else if (numbersPerLine!=0 && numbersPerLine!=numbersInPreviousLine)
                                 throw new IOException("Line "+lines+ " is not the same length as  
the first line.");
                        if (numbersPerLine!=0){numbersInPreviousLine = numbersPerLine;}
                        numbersPerLine = 0;
                }
                initialise = true;
    }



    /** fill a array of array of double */
    private void remplitTab(Reader r) throws IOException {
                int numbers  = 0;
                if (! initialise) {
                        throw new IOException("Run first the countline methode.");
// return;
                }

                int size = width * lines;
                tab = new double[lines][width];
                StreamTokenizer tok = new StreamTokenizer(r);
                tok.resetSyntax();
                tok.wordChars(33, 255);
                tok.whitespaceChars(0, ' ');
                tok.eolIsSignificant(true); // we need the EOF
                tok.parseNumbers(); // we want number
                tok.slashStarComments(true);
                boolean wasNumber = false;
                double previousNb = 0;
                double expo = 0;

               
                int i = 0;
                int j = 0;
                while (tok.nextToken() != StreamTokenizer.TT_EOF) {
                        boolean isScientific = true;
                        if (i==size){
                                throw new IOException("remplitTab: Warning array filled before  
eof");
                        }
                        switch (tok.ttype){
                                case StreamTokenizer.TT_EOL : // start a new line
                                        if(numbers != 0){ //ignore lignes vides
                                                i++;
                                                j=0;
                                                numbers = 0; //remise a zero pour examiner une nouvelle ligne
                                        }
                                        wasNumber = false;
                                        break;
                       
                                case StreamTokenizer.TT_NUMBER:
                                        tab[i][j++] = (double)tok.nval;
                                        numbers++;
                                        wasNumber = true;
                                        previousNb = tab[i][j-1];
                                        break;
                                       
                                case StreamTokenizer.TT_WORD:
        //checking if it is a scientific notation
                                        if ((tok.sval.startsWith("E")) && (tok.sval.length() > 1)){
                                                String  expoStr = tok.sval.split("E")[1];
                                                try{
                                                        expo = Double.parseDouble(expoStr);
                                                }
                                                catch(NumberFormatException e){
                                                        String msg = e.getMessage();
                                                        isScientific = false;
                                                }
                                                if ((isScientific) && (wasNumber) ){
                                                        // overwrite here theNumber on the previous entry in the tab
                                                        tab[i][j-1] = previousNb*Math.pow(10, expo);
                                                }
                                        }
                         break;
                        } //end switch
        } //end while
           // end if (initialise==true)
        initialise = false;
     }

    /** output  */
        private void sortie(String chaine){

// System.out.print(chaine );
                IJ.log(chaine); // print in the log file
// IJ.showStatus(chaine); // print in the status bar
                }
               
               
}   // fin de la classe
----------------------------------
A test file test.txt:

-------------------------------

cola colb colc cold
1 2 3 4
11 12 13 14
21 22 23 24
31 32 33 34