// F-LSFtxtTranslate.js script function by Christophe Leterrier // Translate single-channel txt localization files from Sandrine to .xls ThunderSTORM localization files importClass(Packages.java.io.File); importClass(Packages.java.io.FileReader); importClass(Packages.java.io.FileWriter); importClass(Packages.java.io.BufferedReader); importClass(Packages.java.io.BufferedWriter); importClass(Packages.ij.IJ); importClass(Packages.java.lang.Double); function SLFtxtTranslate(inPath, outDir, outFormat) { // is there a header? var inHeader = true; var FWHM = 2.355; var BgdADU = 100; // Add support for the Z uncertainty (in TS daily buil 05 may 2014) // fixed sigma for XY uncertainty (if fixed) var fixXY = 10; // fixed sigma for Z uncertainty (if fixed) var fixZ = 20; var SampleMax = 100; // var PixelPitch = 160; // var ExposTime = 0.016; // var CpP = 1 / PpC; // var BgdCor = (BgdPhot / PixelPitch) * (BgdPhot / PixelPitch); // var EMfactor = 1.83; // Header format (if exists) if (inHeader == true) var inHeaderNS = ["Channel Name", "X", "Y", "Xc", "Yc", "Height", "Area", "Width", "Phi", "Ax", "BG", "I", "Frame", "Length", "Link", "Valid", "Z", "Zc", "Photons", "Lateral Localization Accuracy", "Xw", "Yw", "Xwc", "Ywc"]; var inSep = " "; // Assign the indexes for all columns in the input format iX = 0; iY = 1; iZ = 2; // Define input file path var inFile = new File(inPath); var inName = inFile.getName(); var inNameExt = getExt("" + inName); IJ.log(" inName: " + inName); // Open input File reader var br = new BufferedReader(new FileReader(inFile)); // Taste the first line to detect if 2D (all Z =0) or 3D if (inHeader == true) inLine = br.readLine(); var inCells = inLine.split(inSep); var zAccu = 0; var i = 0; while ((inLine = br.readLine()) != null && i < SampleMax) { i++; inCells = inLine.split(inSep); zAccu = zAccu + parseFloat(inCells[iZ]); } if (zAccu == 0) IJ.log(" 2D file detected"); else IJ.log(" 3D file detected"); // Close and reopen to get back at line 0 br.close(); br = new BufferedReader(new FileReader(inFile)); // Pass header line if (inHeader == true) inLine = br.readLine(); // ThunderSTORM format if (outFormat == "xls") { var sep = "\t"; if (zAccu == 0){// 2D case var outHeader = ["\"frame\"","\"x [nm]\"","\"y [nm]\"","\"uncertainty_xy [nm]\""]; var outSuffix = "_TS2D"; } else { var outHeader = ["\"frame\"","\"x [nm]\"","\"y [nm]\"","\"z [nm]\"","\"uncertainty_xy [nm]\"", "\"uncertainty_z [nm]\""]; var outSuffix = "_TS3D"; } var includeHeader = true; var outExt = ".xls"; } // Prepare output file path var outName = inName.substring(0, inName.length()-4) + outSuffix + outExt; var outPath = outDir + outName; var outFile = new File(outPath); if (!outFile.exists()) { outFile.createNewFile(); } IJ.log(" outName: " + outName); // Open output File writer var bw = new BufferedWriter(new FileWriter(outFile)); // Write new Header if (includeHeader == true) { var outLine = makeLineFromArray(outHeader, sep); bw.write(outLine); bw.newLine(); } // Write the output file line by line var m = 0; while ((inLine = br.readLine()) != null) { m++; var inCells = inLine.split(inSep); // ThunderSTORM xls format if (outFormat == "xls") { // Build results line if (zAccu == 0){ // 2D case outLine = "1" + sep + parseFloat(inCells[iX]) + sep + parseFloat(inCells[iY]) + sep + fixXY; } else { // 3D case // peak width: TS has Wx and Wy (astigmatism-deformed PSF), but N-STORM has only one width W and an axial ratio Ax // so we calculate Wx and Wy from W and Ax outLine = "1" + sep + parseFloat(inCells[iX]) + sep + parseFloat(inCells[iY]) + sep + parseFloat(inCells[iZ]) + sep + fixXY + sep + fixZ; } } bw.write(outLine); bw.newLine(); } br.close(); bw.close(); } function makeLineFromArray(ar, se) { ol = "" + ar[0]; for (t = 1; t < ar.length; t++) { ol = ol + se + ar[t]; } return ol; } function getExt(filestring){ var namearray = filestring.split("."); var shortname = ""; for (var f = 0; f < namearray.length - 1; f++) { shortname = shortname + namearray[f]; } return [shortname, namearray[namearray.length - 1]]; }