Posted by
Eric Janiaud on
Oct 17, 2005; 2:02pm
URL: http://imagej.273.s1.nabble.com/how-to-read-in-a-text-file-in-a-plugin-tp3704664p3704665.html
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