Changes for page Access data with ImageJ
Last modified by fwilde on 2018/12/18 12:01
Summary
-
Page properties (1 modified, 0 added, 0 removed)
-
Attachments (0 modified, 6 added, 0 removed)
-
Objects (1 modified, 0 added, 0 removed)
Details
- Page properties
-
- Content
-
... ... @@ -1,8 +1,12 @@ 1 1 {{layout}} 2 2 {{layout-section ac:type="two_right_sidebar"}} 3 3 {{layout-cell}} 4 -Currently, at P05 a generic data format is used to store raw and reconstructed data. Generally, this is a binary format in little endian byte order with different data types (uint16, real32, ...) and a header which describes the dataset (rows and columns, data format). This data can either be imported directly in ImageJ or loaded with our plugins. 4 +{{info}} 5 +**As of 2017, all images are stored in TIFF format. These can be easily viewed with many image viewers including ImageJ.** 6 +{{/info}} 5 5 8 +Until 2017 at P05 a generic data format was used to store raw and reconstructed data. This is a binary format in little endian byte order with different data types (uint16, real32, ...) and a header which describes the dataset (rows and columns, data format). This data can either be imported directly in ImageJ or loaded with our plugins. 9 + 6 6 = {{id name="AccessdatawithImageJ-Readthefileheader"/}}Read the file header = 7 7 8 8 Each image contains a header consisting of the information needed to open the binary raw file. To read the header open the first line of the dataset (e.g. with the {{code language="none"}}head{{/code}} command in Linux or in an editor). The header information is subdivided with underscore symbols, like e.g. {{code language="none"}}PC_2_U_2000_2000_{{/code}}. The first item describes on what kind of computer the data was generated. The second item shows the dimensionailty of the data (2 for an image). The next item is a letter (either B U I L or F ) and describes the data type. A list of te data types can be found in the table below. The last items give the length of the dataset in each dimension. The total header length is not fixed and generally depends on the image dimensions.and count all letters until the carriage return. Add 2 to this number (carriage return has two letters) and this is the header length - e.g. {{code language="none"}}PC_2_U_2000_2000_{{/code}} has 17 letters ansd thus results in a header length of 19. ... ... @@ -16,7 +16,7 @@ 16 16 header tag 17 17 ))) 18 18 |((( 19 - 23 +\\ 20 20 )))|((( 21 21 8 bit 22 22 )))|((( ... ... @@ -30,7 +30,7 @@ 30 30 U 31 31 ))) 32 32 |((( 33 - 37 +\\ 34 34 )))|((( 35 35 16 bit Signed 36 36 )))|((( ... ... @@ -37,7 +37,7 @@ 37 37 I 38 38 ))) 39 39 |((( 40 - 44 +\\ 41 41 )))|((( 42 42 32 bit Signed 43 43 )))|((( ... ... @@ -90,9 +90,9 @@ 90 90 [[attach:read_dat.java]] 91 91 {{/panel}} 92 92 93 - 97 +\\ 94 94 95 - 99 +\\ 96 96 {{/layout-cell}} 97 97 98 98 {{layout-cell}}
- HandleExtraFileTypes.class
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.fwilde - Size
-
... ... @@ -1,0 +1,1 @@ 1 +5.8 KB - Content
- HandleExtraFileTypes.jar
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.fwilde - Size
-
... ... @@ -1,0 +1,1 @@ 1 +9.7 KB - Content
- HandleExtraFileTypes.java
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.fwilde - Size
-
... ... @@ -1,0 +1,1 @@ 1 +10.8 KB - Content
-
... ... @@ -1,0 +1,313 @@ 1 +import ij.*; 2 +import ij.plugin.*; 3 +import java.io.*; 4 + 5 +// Plugin to handle file types which are not implemented 6 +// directly in ImageJ through io.Opener 7 +// NB: since there is no _ in the name it will not appear in Plugins menu 8 +// ----- 9 +// Can be user modified so that your own specialised file types 10 +// can be opened through File ... Open 11 +// OR by drag and drop onto the ImageJ main panel 12 +// OR by double clicking in the MacOS 9/X Finder 13 +// ----- 14 +// Go to the point marked MODIFY HERE and modify to 15 +// recognise and load your own file type 16 +// ----- 17 +// Gregory Jefferis - 030629 18 +// jefferis@stanford.edu 19 + 20 +/** 21 + * Plugin to handle file types which are not implemented 22 + * directly in ImageJ through io.Opener. 23 + */ 24 +public class HandleExtraFileTypes extends ImagePlus implements PlugIn { 25 + static final int IMAGE_OPENED = -1; 26 + static final int PLUGIN_NOT_FOUND = -2; 27 + 28 + /** Called from io/Opener.java. */ 29 + public void run(String path) { 30 + if (path.equals("")) return; 31 + File theFile = new File(path); 32 + String directory = theFile.getParent(); 33 + String fileName = theFile.getName(); 34 + if (directory == null) directory = ""; 35 + 36 + // Try and recognise file type and load the file if recognised 37 + ImagePlus imp = openImage(directory, fileName, path); 38 + if (imp==null) { 39 + IJ.showStatus(""); 40 + return; // failed to load file or plugin has opened and displayed it 41 + } 42 + ImageStack stack = imp.getStack(); 43 + // get the title from the stack (falling back to the fileName) 44 + String title=imp.getTitle().equals("")?fileName:imp.getTitle(); 45 + // set the stack of this HandleExtraFileTypes object 46 + // to that attached to the ImagePlus object returned by openImage() 47 + setStack(title, stack); 48 + // copy over the calibration info since it doesn't come with the ImageProcessor 49 + setCalibration(imp.getCalibration()); 50 + // also copy the Show Info field over if it exists 51 + if (imp.getProperty("Info") != null) 52 + setProperty("Info", imp.getProperty("Info")); 53 + // copy the FileInfo 54 + setFileInfo(imp.getOriginalFileInfo()); 55 + // copy dimensions 56 + if (IJ.getVersion().compareTo("1.38s")>=0) 57 + setDimensions(imp.getNChannels(), imp.getNSlices(), imp.getNFrames()); 58 + // copy the image subtitle field ("Label" property) if it exists 59 + if (imp.getProperty("Label")!=null) 60 + setProperty("Label", imp.getProperty("Label")); 61 + if (IJ.getVersion().compareTo("1.41o")>=0) 62 + setOpenAsHyperStack(imp.getOpenAsHyperStack()); 63 + } 64 + 65 + 66 + private Object tryOpen(String directory, String name, String path) { 67 + // set up a stream to read in 132 bytes from the file header 68 + // These can be checked for "magic" values which are diagnostic 69 + // of some image types 70 + InputStream is; 71 + byte[] buf = new byte[132]; 72 + try { 73 + if (0 == path.indexOf("http://")) 74 + is = new java.net.URL(path).openStream(); 75 + else 76 + is = new FileInputStream(path); 77 + is.read(buf, 0, 132); 78 + is.close(); 79 + } 80 + catch (IOException e) { 81 + // couldn't open the file for reading 82 + return null; 83 + } 84 + name = name.toLowerCase(); 85 + width = PLUGIN_NOT_FOUND; 86 + 87 + // Temporarily suppress "plugin not found" errors if LOCI Bio-Formats plugin is installed 88 + if (Menus.getCommands().get("Bio-Formats Importer")!=null && IJ.getVersion().compareTo("1.37u")>=0) 89 + IJ.suppressPluginNotFoundError(); 90 + 91 + // OK now we get to the interesting bit 92 + 93 + // GJ: added Biorad PIC confocal file handler 94 + // ------------------------------------------ 95 + // These make 12345 if you read them as the right kind of short 96 + // and should have this value in every Biorad PIC file 97 + if (buf[54]==57 && buf[55]==48) { 98 + return tryPlugIn("Biorad_Reader", path); 99 + } 100 + // GJ: added Gatan Digital Micrograph DM3 handler 101 + // ---------------------------------------------- 102 + // check if the file ends in .DM3 or .dm3, 103 + // and bytes make an int value of 3 which is the DM3 version number 104 + if (name.endsWith(".dm3") && buf[0]==0 && buf[1]==0 && buf[2]==0 && buf[3]==3) { 105 + return tryPlugIn("DM3_Reader", path); 106 + } 107 + 108 + // IPLab file handler 109 + // Little-endian IPLab files start with "iiii" or "mmmm". 110 + if (name.endsWith(".ipl") || 111 + (buf[0]==105 && buf[1]==105 && buf[2]==105 && buf[3]==105) || 112 + (buf[0]==109 && buf[1]==109 && buf[2]==109 && buf[3]==109)) { 113 + return tryPlugIn("IPLab_Reader", path); 114 + } 115 + 116 + // Packard InstantImager format (.img) handler -> check HERE 117 + // before Analyze check below! 118 + // Check extension and signature bytes KAJ_ 119 + //if (name.endsWith(".img") && buf[0]==75 && buf[1]==65 && buf[2]==74 && buf[3]==0) { 120 + // return tryPlugIn("InstantImager_Reader", path); 121 + //} 122 + 123 + // Analyze format (.img/.hdr) handler 124 + // Opens the file using the Nifti_Reader if it is installed, 125 + // otherwise the Analyze_Reader is used. Note that 126 + // the Analyze_Reader plugin opens and displays the 127 + // image and does not implement the ImagePlus class. 128 + 129 + 130 + // NIFTI format (.nii) handler 131 + if (name.endsWith(".nii") || name.endsWith( ".nii.gz" ) || name.endsWith( ".nii.z" ) ) { 132 + return tryPlugIn("Nifti_Reader", path); 133 + } 134 + 135 + // Image Cytometry Standard (.ics) handler 136 + // http://valelab.ucsf.edu/~nico/IJplugins/Ics_Opener.html 137 + if (name.endsWith(".ics")) { 138 + return tryPlugIn("Ics_Opener", path); 139 + } 140 + 141 + // Princeton Instruments SPE image file (.spe) handler 142 + // http://rsb.info.nih.gov/ij/plugins/spe.html 143 + if (name.endsWith(".spe")) { 144 + return tryPlugIn("OpenSPE_", path); 145 + } 146 + 147 + // Zeiss Confocal LSM 510 image file (.lsm) handler 148 + // http://rsb.info.nih.gov/ij/plugins/lsm-reader.html 149 + if (name.endsWith(".lsm")) { 150 + Object obj = tryPlugIn("LSM_Reader", path); 151 + if (obj==null && Menus.getCommands().get("Show LSMToolbox")!=null) 152 + obj = tryPlugIn("LSM_Toolbox", "file="+path); 153 + return obj; 154 + } 155 + 156 + // BM: added Bruker file handler 29.07.04 157 + if (name.equals("ser") || name.equals("fid") || name.equals("2rr") || 158 + name.equals("2ii") || name.equals("3rrr") || name.equals("3iii") || 159 + name.equals("2dseq")) { 160 + ij.IJ.showStatus("Opening Bruker " + name + " File"); 161 + return tryPlugIn("BrukerOpener", name + "|" + path); 162 + } 163 + 164 + // AVI: open AVI files using AVI_Reader plugin 165 + if (name.endsWith(".avi")) { 166 + return tryPlugIn("AVI_Reader", path); 167 + } 168 + 169 + // QuickTime: open .mov and .pict files using QT_Movie_Opener plugin 170 + if (name.endsWith(".mov") || name.endsWith(".pict")) { 171 + return tryPlugIn("QT_Movie_Opener", path); 172 + } 173 + 174 + // ZVI file handler 175 + // Little-endian ZVI and Thumbs.db files start with d0 cf 11 e0 176 + // so we can only look at the extension. 177 + if (name.endsWith(".zvi")) { 178 + return tryPlugIn("ZVI_Reader", path); 179 + } 180 + 181 + // University of North Carolina (UNC) file format handler 182 + // 'magic' numbers are (int) offsets to data structures and 183 + // may change in future releases. 184 + if (name.endsWith(".unc") || (buf[3]==117 && buf[7]==-127 && buf[11]==36 && buf[14]==32 && buf[15]==-127)) { 185 + return tryPlugIn("UNC_Reader", path); 186 + } 187 + 188 + // Amira file handler 189 + // http://wbgn013.biozentrum.uni-wuerzburg.de/ImageJ/amira-io.html 190 + if (buf[0]==0x23 && buf[1]==0x20 && buf[2]==0x41 191 + && buf[3]==0x6d && buf[4]==0x69 && buf[5]==0x72 192 + && buf[6]==0x61 && buf[7]==0x4d && buf[8]==0x65 193 + && buf[9]==0x73&&buf[10]==0x68 && buf[11]==0x20) { 194 + return tryPlugIn("AmiraMeshReader_", path); 195 + } 196 + 197 + // Deltavision file handler 198 + // Open DV files generated on Applied Precision DeltaVision systems 199 + if (name.endsWith(".dv") || name.endsWith(".r3d")) { 200 + return tryPlugIn("Deltavision_Opener", path); 201 + } 202 + 203 + // Albert Cardona: read .mrc files (little endian). 204 + // Documentation at: http://ami.scripps.edu/prtl_data/mrc_specification.htm. 205 + // The parsing of the header is a bare minimum of what could be done. 206 + if (name.endsWith(".mrc")) { 207 + return tryPlugIn("Open_MRC_Leginon", path); 208 + } 209 + 210 + // Albert Cardona: read .dat files from the EMMENU software 211 + if (name.endsWith(".dat") && 1 == buf[1] && 0 == buf[2]) { // 'new format' only 212 + return tryPlugIn("Open_DAT_EMMENU", path); 213 + } 214 + 215 + // Timo Rantalainen and Michael Doube: read Stratec pQCT files. 216 + // File name is IDDDDDDD.MHH, where D is decimal and H is hex. 217 + if (name.matches("[iI]\\d{7}\\.[mM]\\p{XDigit}{2}")) { 218 + return tryPlugIn("org.doube.bonej.pqct.Read_Stratec_File", path); 219 + } 220 + 221 + //Michael Doube: read Scanco ISQ files 222 + //File name is ADDDDDDD.ISQ;D where D is a decimal and A is a letter 223 + try { 224 + String isqMagic=new String(buf,0,16,"UTF-8"); 225 + if (name.matches("[a-z]\\d{7}.isq;\\d+") || isqMagic.equals("CTDATA-HEADER_V1")) 226 + return tryPlugIn("org.bonej.io.ISQReader", path); 227 + } 228 + catch (Exception e) {} 229 + 230 + // Jerome Parent : read .bin from the LynceeTec's software Koala 231 + if (name.endsWith(".bin")) { 232 + return tryPlugIn("Koala_Bin_Reader", path); 233 + } 234 + 235 + //HZG-Tomo file format 236 + if (name.endsWith(".img") || name.endsWith(".ref") || name.endsWith(".dar") || name.endsWith(".sin") || name.endsWith(".sis") || name.endsWith(".sli") || name.endsWith(".comp")) { 237 + return tryPlugIn("read_dat", path); 238 + } 239 + 240 + 241 + // ****************** MODIFY HERE ****************** 242 + // do what ever you have to do to recognise your own file type 243 + // and then call appropriate plugin using the above as models 244 + // e.g.: 245 + 246 + /* 247 + // A. Dent: Added XYZ handler 248 + // ---------------------------------------------- 249 + // check if the file ends in .xyz, and bytes 0 and 1 equal 42 250 + if (name.endsWith(".xyz") && buf[0]==42 && buf[1]==42) { 251 + // Ok we've identified the file type - now load it 252 + return tryPlugIn("XYZ_Reader", path); 253 + } 254 + */ 255 + 256 + return null; 257 + } 258 + 259 + private ImagePlus openImage(String directory, String name, String path) { 260 + Object o = tryOpen(directory, name, path); 261 + // if an image was returned, assume success 262 + if (o instanceof ImagePlus) return (ImagePlus)o; 263 + 264 + // try opening the file with LOCI Bio-Formats plugin - always check this last! 265 + // Do not call Bio-Formats if File>Import>Image Sequence is opening this file. 266 + if (o==null && (IJ.getVersion().compareTo("1.38j")<0||!IJ.redirectingErrorMessages()) && (new File(path).exists())) { 267 + Object loci = IJ.runPlugIn("loci.plugins.LociImporter", path); 268 + if (loci!=null) { 269 + // plugin exists and was launched 270 + try { 271 + // check whether plugin was successful 272 + Class c = loci.getClass(); 273 + boolean success = c.getField("success").getBoolean(loci); 274 + boolean canceled = c.getField("canceled").getBoolean(loci); 275 + if (success || canceled) { 276 + width = IMAGE_OPENED; 277 + return null; 278 + } 279 + } 280 + catch (Exception exc) { } 281 + } 282 + } 283 + 284 + return null; 285 + 286 + } // openImage 287 + 288 + /** 289 + * Attempts to open the specified path with the given plugin. If the 290 + * plugin extends the ImagePlus class (e.g., BioRad_Reader), set 291 + * extendsImagePlus to true, otherwise (e.g., LSM_Reader) set it to false. 292 + * 293 + * @return A reference to the plugin, if it was successful. 294 + */ 295 + private Object tryPlugIn(String className, String path) { 296 + Object o = IJ.runPlugIn(className, path); 297 + if (o instanceof ImagePlus) { 298 + // plugin extends ImagePlus class 299 + ImagePlus imp = (ImagePlus)o; 300 + if (imp.getWidth()==0) 301 + o = null; // invalid image 302 + else 303 + width = IMAGE_OPENED; // success 304 + } else { 305 + // plugin does not extend ImagePlus; assume success 306 + width = IMAGE_OPENED; 307 + } 308 + return o; 309 + } 310 + 311 + 312 +} 313 +
- imagej_raw_import.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.fwilde - Size
-
... ... @@ -1,0 +1,1 @@ 1 +11.9 KB - Content
- read_dat.class
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.fwilde - Size
-
... ... @@ -1,0 +1,1 @@ 1 +5.0 KB - Content
- read_dat.java
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.fwilde - Size
-
... ... @@ -1,0 +1,1 @@ 1 +5.2 KB - Content
-
... ... @@ -1,0 +1,147 @@ 1 +import ij.IJ; 2 +import ij.ImagePlus; 3 + 4 +import ij.io.FileInfo; 5 +import ij.io.FileOpener; 6 +import ij.io.OpenDialog; 7 + 8 +import ij.plugin.PlugIn; 9 + 10 +import ij.process.ByteProcessor; 11 + 12 +import java.io.DataInputStream; 13 +import java.io.InputStream; 14 +import java.io.File; 15 +import java.io.FileInputStream; 16 +import java.io.IOException; 17 +import java.util.Arrays; 18 +import java.util.HashMap; 19 +import java.util.Map; 20 + 21 +public class read_dat extends ImagePlus implements PlugIn { 22 + 23 + public void run(String arg) { 24 + String path = getPath(arg); 25 + if (null == path) return; 26 + if (!parse(path)) return; 27 + if (null == arg || 0 == arg.trim().length()) this.show(); // was opened by direct call to the plugin 28 + // not via HandleExtraFileTypes which would 29 + // have given a non-null arg. 30 + } 31 + 32 + /** Accepts URLs as well. */ 33 + private String getPath(String arg) { 34 + if (null != arg) { 35 + if (0 == arg.indexOf("http://") 36 + || new File(arg).exists()) return arg; 37 + } 38 + // else, ask: 39 + OpenDialog od = new OpenDialog("Choose a file", null); 40 + String dir = od.getDirectory(); 41 + if (null == dir) return null; // dialog was canceled 42 + dir = dir.replace('\\', '/'); // Windows safe 43 + if (!dir.endsWith("/")) dir += "/"; 44 + return dir + od.getFileName(); 45 + } 46 + 47 + /** Opens URLs as well. */ 48 + private InputStream open(String path) throws Exception { 49 + if (0 == path.indexOf("http://")) 50 + return new java.net.URL(path).openStream(); 51 + return new FileInputStream(path); 52 + } 53 + 54 + private boolean parse(String path) { 55 + // Open file and read header 56 + byte[] buf = new byte[136]; 57 + try { 58 + InputStream is = open(path); 59 + is.read(buf, 0, 136); 60 + is.close(); 61 + } catch (Exception e) { 62 + e.printStackTrace(); 63 + return false; 64 + } 65 + // Analyze image header 66 + // split off first 40 characters of the file and convert them to String 67 + byte[] subarray_buf = Arrays.copyOfRange(buf, 0, 40); 68 + String firstchars = new String(subarray_buf); 69 + // split the first character at the newline 70 + String[] splitted_chars = firstchars.split("\\r\\n"); 71 + // read the actual header 72 + String header = splitted_chars[0]; 73 + // get the header length 74 + int header_length = header.length(); 75 + // split the header for individual information 76 + String[] header_atoms = header.split("_"); 77 + // header: computer information 78 + String hdr_comp = header_atoms[0]; 79 + // header: number of dimensions 80 + int hdr_arrdim = Integer.parseInt(header_atoms[1]); 81 + // header: IDL data type 82 + String hdr_idltype = header_atoms[2]; 83 + // header: (variable length) array with the dimension sizes 84 + String[] hdr_dimsize = Arrays.copyOfRange(header_atoms, 3, header_atoms.length); 85 + 86 + Map<String, Integer> idlToImagej = new HashMap<String, Integer>(); 87 + idlToImagej.put("B", 0); // "GRAY8" 88 + idlToImagej.put("I", 1); // "GRAY16_SIGNED" 89 + idlToImagej.put("U", 2); // "GRAY16_UNSIGNED" 90 + idlToImagej.put("L", 3); // "GRAY32_INT" 91 + idlToImagej.put("F", 4); // "GRAY32_FLOAT" 92 + 93 + // Read width,height,slices ... from the header 94 + /* THIS IS AN EXAMPLE */ 95 + int n_slices = 1; 96 + int height = 1; 97 + int width = Integer.parseInt(hdr_dimsize[0]); 98 + if (hdr_dimsize.length >= 2) { 99 + height = Integer.parseInt(hdr_dimsize[1]); 100 + } 101 + if (hdr_dimsize.length >= 3) { 102 + n_slices = Integer.parseInt(hdr_dimsize[2]); 103 + } 104 + int type = idlToImagej.get(hdr_idltype); 105 + 106 + 107 + // Build a new FileInfo object with all file format parameters and file data 108 + FileInfo fi = new FileInfo(); 109 + fi.fileType = type; 110 + fi.fileFormat = fi.RAW; 111 + int islash = path.lastIndexOf('/'); 112 + if (0 == path.indexOf("http://")) { 113 + fi.url = path; 114 + } else { 115 + fi.directory = path.substring(0, islash+1); 116 + } 117 + fi.fileName = path.substring(islash+1); 118 + fi.width = width; 119 + fi.height = height; 120 + fi.nImages = n_slices; 121 + fi.gapBetweenImages = 0; 122 + fi.intelByteOrder = true; // little endian 123 + fi.whiteIsZero = false; // no inverted LUT 124 + fi.longOffset = fi.offset = (header_length + 2); // header size in bytes +2 for newline 125 + 126 + // Now make a new ImagePlus out of the FileInfo 127 + // and integrate its data into this PlugIn, which is also an ImagePlus 128 + try { 129 + FileOpener fo = new FileOpener(fi); 130 + ImagePlus imp = fo.open(false); 131 + this.setStack(imp.getTitle(), imp.getStack()); 132 + this.setCalibration(imp.getCalibration()); 133 + Object obinfo = imp.getProperty("Info"); 134 + if (null != obinfo) this.setProperty("Info", obinfo); 135 + this.setFileInfo(imp.getOriginalFileInfo()); 136 + } catch (Exception e) { 137 + e.printStackTrace(); 138 + return false; 139 + } 140 + return true; 141 + } 142 + 143 + //private final int readIntLittleEndian(byte[] buf, int start) { 144 + // return (buf[start]) + (buf[start+1]<<8) + (buf[start+2]<<16) + (buf[start+3]<<24); 145 + //} 146 +} 147 +
- Confluence.Code.ConfluencePageClass[0]
-
- Id
-
... ... @@ -1,1 +1,1 @@ 1 - 1166020681 +34870216 - URL
-
... ... @@ -1,1 +1,1 @@ 1 -https://confluence.desy.de/spaces/P5I/pages/ 116602068/Access data with ImageJ1 +https://confluence.desy.de/spaces/P5I/pages/34870216/Access data with ImageJ