Changeset 5703


Ignore:
Timestamp:
11/17/09 15:13:27 (10 years ago)
Author:
melissa
Message:

Fixed LUT parsing for multi-file BioRad datasets.

Files:
4 edited

Legend:

Unmodified
Added
Removed
  • branches/4.1/components/bio-formats/src/loci/formats/AxisGuesser.java

    r5093 r5703  
    7272 
    7373  /** Prefix endings indicating series dimension. */ 
    74   protected static final String[] S = {"s", "series", "e", "sp"}; 
     74  protected static final String[] S = {"s", "series", "sp"}; 
    7575 
    7676  protected static final BigInteger TWO = new BigInteger("2"); 
  • branches/4.1/components/bio-formats/src/loci/formats/in/BioRadReader.java

    r5664 r5703  
    9696  public static final String[] PIC_SUFFIX = {"pic"}; 
    9797 
     98  public static final int LUT_LENGTH = 256; 
     99 
    98100  // -- Fields -- 
    99101 
     
    104106  private byte[][][] lut; 
    105107  private int lastChannel; 
     108  private boolean brokenNotes = false; 
    106109 
    107110  private Vector<Note> noteStrings; 
     
    209212      noteStrings = null; 
    210213      offset = gain = null; 
     214      brokenNotes = false; 
    211215    } 
    212216  } 
     
    332336 
    333337    // read notes 
    334     int noteCount = 0; 
    335     boolean brokenNotes = false; 
    336     while (notes) { 
    337       // read in note 
    338  
    339       Note n = new Note(); 
    340       n.level = in.readShort(); 
    341       notes = in.readInt() != 0; 
    342       n.num = in.readShort(); 
    343       n.status = in.readShort(); 
    344       n.type = in.readShort(); 
    345       n.x = in.readShort(); 
    346       n.y = in.readShort(); 
    347       n.p = in.readString(80); 
    348  
    349       if (n.type < 0 || n.type >= NOTE_NAMES.length) { 
    350         notes = false; 
    351         brokenNotes = true; 
    352         break; 
    353       } 
    354  
    355       // be sure to remove binary data from the note text 
    356       int ndx = n.p.length(); 
    357       for (int i=0; i<n.p.length(); i++) { 
    358         if (n.p.charAt(i) == 0) { 
    359           ndx = i; 
    360           break; 
    361         } 
    362       } 
    363  
    364       n.p = n.p.substring(0, ndx).trim(); 
    365  
    366       String value = n.p.replaceAll("=", ""); 
    367       Vector<String> v = new Vector<String>(); 
    368       StringTokenizer t = new StringTokenizer(value, " "); 
    369       while (t.hasMoreTokens()) { 
    370         String token = t.nextToken().trim(); 
    371         if (token.length() > 0) v.add(token); 
    372       } 
    373       String[] tokens = v.toArray(new String[v.size()]); 
    374       try { 
    375         if (tokens.length > 1) { 
    376           int noteType = Integer.parseInt(tokens[1]); 
    377  
    378           if (noteType == 2 && value.indexOf("AXIS_4") != -1) { 
    379             core[0].sizeZ = 1; 
    380             core[0].sizeT = getImageCount(); 
    381             core[0].orderCertain = true; 
    382           } 
    383         } 
    384       } 
    385       catch (NumberFormatException e) { } 
    386  
    387       // add note to list 
    388       noteCount++; 
    389  
    390       noteStrings.add(n); 
    391     } 
    392  
    393     status("Reading color table"); 
    394  
    395     // read color tables 
    396     int numLuts = 0; 
    397     lut = new byte[3][3][256]; 
    398     boolean eof = false; 
    399     int next = 0; 
    400     while (!eof && numLuts < 3 && !brokenNotes) { 
    401       if (in.getFilePointer() + lut[numLuts][next].length <= in.length()) { 
    402         in.read(lut[numLuts][next++]); 
    403         if (next == 3) { 
    404           next = 0; 
    405           numLuts++; 
    406         } 
    407       } 
    408       else eof = true; 
    409       if (eof && numLuts == 0) lut = null; 
    410     } 
    411     if (brokenNotes) lut = null; 
    412  
    413  
    414     String message = numLuts + " color table" + (numLuts == 1 ? "" : "s") + 
    415       " present."; 
    416     debug(message, 2); 
     338 
     339    readNotes(in, true); 
    417340 
    418341    status("Populating metadata"); 
     
    455378    } 
    456379 
    457     core[0].indexed = lut != null; 
    458  
    459380    // populate Pixels 
    460381 
     
    464385 
    465386    boolean multipleFiles = false; 
    466     for (Note n : noteStrings) { 
     387    for (int noteIndex=0; noteIndex<noteStrings.size(); noteIndex++) { 
     388      Note n = noteStrings.get(noteIndex); 
    467389      switch (n.type) { 
    468390        case NOTE_TYPE_USER: 
    469391          // TODO : this should be an overlay 
    470           addGlobalMeta("Note #" + noteCount, n.toString()); 
     392          addGlobalMeta("Note #" + noteIndex, n.toString()); 
    471393          break; 
    472394        case NOTE_TYPE_SCALEBAR: 
     
    476398          // where <length> is the length of the scalebar in microns, 
    477399          // and <angle> is the angle in degrees 
    478           addGlobalMeta("Note #" + noteCount, n.toString()); 
     400          addGlobalMeta("Note #" + noteIndex, n.toString()); 
    479401          break; 
    480402        case NOTE_TYPE_ARROW: 
     
    485407          // <angle> is the angle in degrees and <fill> is either "Fill" or 
    486408          // "Outline" 
    487           addGlobalMeta("Note #" + noteCount, n.toString()); 
     409          addGlobalMeta("Note #" + noteIndex, n.toString()); 
    488410          break; 
    489411        case NOTE_TYPE_VARIABLE: 
     
    570492          } 
    571493          else { 
    572             addGlobalMeta("Note #" + noteCount, n.toString()); 
     494            addGlobalMeta("Note #" + noteIndex, n.toString()); 
    573495          } 
    574496          break; 
     
    815737        default: 
    816738          // notes for display only 
    817           addGlobalMeta("Note #" + noteCount, n.toString()); 
     739          addGlobalMeta("Note #" + noteIndex, n.toString()); 
    818740      } 
    819741 
     
    932854    else picFiles = null; 
    933855 
     856    status("Reading lookup tables"); 
     857 
     858    lut = new byte[getEffectiveSizeC()][][]; 
     859    for (int channel=0; channel<lut.length; channel++) { 
     860      int plane = getIndex(0, channel, 0); 
     861      String file = 
     862        picFiles == null ? currentId : picFiles[plane % picFiles.length]; 
     863      debug("reading table for C = " + channel + " from " + file, 2); 
     864      RandomAccessInputStream s = new RandomAccessInputStream(file); 
     865      s.order(true); 
     866      readLookupTables(s); 
     867      s.close(); 
     868      if (lut == null) break; 
     869    } 
     870    core[0].indexed = lut != null; 
     871 
    934872    MetadataTools.populatePixels(store, this); 
    935873    MetadataTools.setDefaultCreationDate(store, id, 0); 
     
    969907      } 
    970908    } 
     909  } 
     910 
     911  // -- Helper methods -- 
     912 
     913  /** 
     914   * Read all of the note strings from the given file.  If the 'add' flag is 
     915   * set, the notes will be added to the 'noteStrings' list. 
     916   */ 
     917  private void readNotes(RandomAccessInputStream s, boolean add) 
     918    throws IOException 
     919  { 
     920    s.seek(70); 
     921    int imageLen = getSizeX() * getSizeY(); 
     922    if (picFiles == null) imageLen *= getImageCount(); 
     923    else { 
     924      imageLen *= (getImageCount() / picFiles.length); 
     925    } 
     926    int bpp = FormatTools.getBytesPerPixel(getPixelType()); 
     927    s.skipBytes(bpp * imageLen + 6); 
     928 
     929    boolean notes = true; 
     930    while (notes) { 
     931      // read in note 
     932 
     933      Note n = new Note(); 
     934      n.level = s.readShort(); 
     935      notes = s.readInt() != 0; 
     936      n.num = s.readShort(); 
     937      n.status = s.readShort(); 
     938      n.type = s.readShort(); 
     939      n.x = s.readShort(); 
     940      n.y = s.readShort(); 
     941      n.p = s.readString(80); 
     942 
     943      if (n.type < 0 || n.type >= NOTE_NAMES.length) { 
     944        notes = false; 
     945        brokenNotes = true; 
     946        break; 
     947      } 
     948 
     949      if (!add) continue; 
     950 
     951      // be sure to remove binary data from the note text 
     952      int ndx = n.p.length(); 
     953      for (int i=0; i<n.p.length(); i++) { 
     954        if (n.p.charAt(i) == 0) { 
     955          ndx = i; 
     956          break; 
     957        } 
     958      } 
     959 
     960      n.p = n.p.substring(0, ndx).trim(); 
     961 
     962      String value = n.p.replaceAll("=", ""); 
     963      Vector<String> v = new Vector<String>(); 
     964      StringTokenizer t = new StringTokenizer(value, " "); 
     965      while (t.hasMoreTokens()) { 
     966        String token = t.nextToken().trim(); 
     967        if (token.length() > 0) v.add(token); 
     968      } 
     969      String[] tokens = v.toArray(new String[v.size()]); 
     970      try { 
     971        if (tokens.length > 1) { 
     972          int noteType = Integer.parseInt(tokens[1]); 
     973 
     974          if (noteType == 2 && value.indexOf("AXIS_4") != -1) { 
     975            core[0].sizeZ = 1; 
     976            core[0].sizeT = getImageCount(); 
     977            core[0].orderCertain = true; 
     978          } 
     979        } 
     980      } 
     981      catch (NumberFormatException e) { } 
     982 
     983      // add note to list 
     984      noteStrings.add(n); 
     985    } 
     986  } 
     987 
     988  /** 
     989   * Read all lookup tables from the given file into the 'lut' variable. 
     990   */ 
     991  private void readLookupTables(RandomAccessInputStream s) throws IOException { 
     992    int channel = 0; 
     993    while (channel < lut.length && lut[channel] != null) channel++; 
     994    if (channel >= lut.length) return; 
     995 
     996    readNotes(s, false); 
     997 
     998    // read color tables 
     999    boolean eof = false; 
     1000    int next = 0; 
     1001    while (!eof && channel < lut.length && !brokenNotes) { 
     1002      if (s.getFilePointer() + LUT_LENGTH <= s.length()) { 
     1003        if (lut[channel] == null) { 
     1004          lut[channel] = new byte[3][LUT_LENGTH]; 
     1005        } 
     1006 
     1007        s.read(lut[channel][next++]); 
     1008        if (next == 3) { 
     1009          next = 0; 
     1010          channel++; 
     1011        } 
     1012      } 
     1013      else eof = true; 
     1014      if (eof && channel == 0) { 
     1015        lut = null; 
     1016      } 
     1017    } 
     1018    if (brokenNotes) lut = null; 
    9711019  } 
    9721020 
  • trunk/components/bio-formats/src/loci/formats/AxisGuesser.java

    r5093 r5703  
    7272 
    7373  /** Prefix endings indicating series dimension. */ 
    74   protected static final String[] S = {"s", "series", "e", "sp"}; 
     74  protected static final String[] S = {"s", "series", "sp"}; 
    7575 
    7676  protected static final BigInteger TWO = new BigInteger("2"); 
  • trunk/components/bio-formats/src/loci/formats/in/BioRadReader.java

    r5664 r5703  
    9696  public static final String[] PIC_SUFFIX = {"pic"}; 
    9797 
     98  public static final int LUT_LENGTH = 256; 
     99 
    98100  // -- Fields -- 
    99101 
     
    104106  private byte[][][] lut; 
    105107  private int lastChannel; 
     108  private boolean brokenNotes = false; 
    106109 
    107110  private Vector<Note> noteStrings; 
     
    209212      noteStrings = null; 
    210213      offset = gain = null; 
     214      brokenNotes = false; 
    211215    } 
    212216  } 
     
    332336 
    333337    // read notes 
    334     int noteCount = 0; 
    335     boolean brokenNotes = false; 
    336     while (notes) { 
    337       // read in note 
    338  
    339       Note n = new Note(); 
    340       n.level = in.readShort(); 
    341       notes = in.readInt() != 0; 
    342       n.num = in.readShort(); 
    343       n.status = in.readShort(); 
    344       n.type = in.readShort(); 
    345       n.x = in.readShort(); 
    346       n.y = in.readShort(); 
    347       n.p = in.readString(80); 
    348  
    349       if (n.type < 0 || n.type >= NOTE_NAMES.length) { 
    350         notes = false; 
    351         brokenNotes = true; 
    352         break; 
    353       } 
    354  
    355       // be sure to remove binary data from the note text 
    356       int ndx = n.p.length(); 
    357       for (int i=0; i<n.p.length(); i++) { 
    358         if (n.p.charAt(i) == 0) { 
    359           ndx = i; 
    360           break; 
    361         } 
    362       } 
    363  
    364       n.p = n.p.substring(0, ndx).trim(); 
    365  
    366       String value = n.p.replaceAll("=", ""); 
    367       Vector<String> v = new Vector<String>(); 
    368       StringTokenizer t = new StringTokenizer(value, " "); 
    369       while (t.hasMoreTokens()) { 
    370         String token = t.nextToken().trim(); 
    371         if (token.length() > 0) v.add(token); 
    372       } 
    373       String[] tokens = v.toArray(new String[v.size()]); 
    374       try { 
    375         if (tokens.length > 1) { 
    376           int noteType = Integer.parseInt(tokens[1]); 
    377  
    378           if (noteType == 2 && value.indexOf("AXIS_4") != -1) { 
    379             core[0].sizeZ = 1; 
    380             core[0].sizeT = getImageCount(); 
    381             core[0].orderCertain = true; 
    382           } 
    383         } 
    384       } 
    385       catch (NumberFormatException e) { } 
    386  
    387       // add note to list 
    388       noteCount++; 
    389  
    390       noteStrings.add(n); 
    391     } 
    392  
    393     status("Reading color table"); 
    394  
    395     // read color tables 
    396     int numLuts = 0; 
    397     lut = new byte[3][3][256]; 
    398     boolean eof = false; 
    399     int next = 0; 
    400     while (!eof && numLuts < 3 && !brokenNotes) { 
    401       if (in.getFilePointer() + lut[numLuts][next].length <= in.length()) { 
    402         in.read(lut[numLuts][next++]); 
    403         if (next == 3) { 
    404           next = 0; 
    405           numLuts++; 
    406         } 
    407       } 
    408       else eof = true; 
    409       if (eof && numLuts == 0) lut = null; 
    410     } 
    411     if (brokenNotes) lut = null; 
    412  
    413  
    414     String message = numLuts + " color table" + (numLuts == 1 ? "" : "s") + 
    415       " present."; 
    416     debug(message, 2); 
     338 
     339    readNotes(in, true); 
    417340 
    418341    status("Populating metadata"); 
     
    455378    } 
    456379 
    457     core[0].indexed = lut != null; 
    458  
    459380    // populate Pixels 
    460381 
     
    464385 
    465386    boolean multipleFiles = false; 
    466     for (Note n : noteStrings) { 
     387    for (int noteIndex=0; noteIndex<noteStrings.size(); noteIndex++) { 
     388      Note n = noteStrings.get(noteIndex); 
    467389      switch (n.type) { 
    468390        case NOTE_TYPE_USER: 
    469391          // TODO : this should be an overlay 
    470           addGlobalMeta("Note #" + noteCount, n.toString()); 
     392          addGlobalMeta("Note #" + noteIndex, n.toString()); 
    471393          break; 
    472394        case NOTE_TYPE_SCALEBAR: 
     
    476398          // where <length> is the length of the scalebar in microns, 
    477399          // and <angle> is the angle in degrees 
    478           addGlobalMeta("Note #" + noteCount, n.toString()); 
     400          addGlobalMeta("Note #" + noteIndex, n.toString()); 
    479401          break; 
    480402        case NOTE_TYPE_ARROW: 
     
    485407          // <angle> is the angle in degrees and <fill> is either "Fill" or 
    486408          // "Outline" 
    487           addGlobalMeta("Note #" + noteCount, n.toString()); 
     409          addGlobalMeta("Note #" + noteIndex, n.toString()); 
    488410          break; 
    489411        case NOTE_TYPE_VARIABLE: 
     
    498420            else if (key.equals("INFO_OBJECTIVE_MAGNIFICATION")) { 
    499421              store.setObjectiveNominalMagnification( 
    500                 new Integer((int) Double.parseDouble(value)), 0, 0); 
     422                new Integer((int) Float.parseFloat(value)), 0, 0); 
    501423            } 
    502424            else if (key.equals("LENS_MAGNIFICATION")) { 
    503425              store.setObjectiveNominalMagnification( 
    504                 new Integer((int) Double.parseDouble(value)), 0, 0); 
     426                new Integer((int) Float.parseFloat(value)), 0, 0); 
    505427            } 
    506428            else if (key.startsWith("SETTING")) { 
     
    570492          } 
    571493          else { 
    572             addGlobalMeta("Note #" + noteCount, n.toString()); 
     494            addGlobalMeta("Note #" + noteIndex, n.toString()); 
    573495          } 
    574496          break; 
     
    599521 
    600522                store.setObjectiveNominalMagnification( 
    601                   new Integer((int) Double.parseDouble(values[11])), 0, 0); 
     523                  new Integer((int) Float.parseFloat(values[11])), 0, 0); 
    602524                store.setDimensionsPhysicalSizeZ(new Double(values[14]), 0, 0); 
    603525                break; 
     
    610532                addGlobalMeta("Scan area height", values[5]); 
    611533 
    612                 double width = 
    613                   Double.parseDouble(values[4]) - Double.parseDouble(values[2]); 
     534                float width = 
     535                  Float.parseFloat(values[4]) - Float.parseFloat(values[2]); 
    614536                width /= getSizeX(); 
    615                 double height = 
    616                   Double.parseDouble(values[5]) - Double.parseDouble(values[3]); 
     537                float height = 
     538                  Float.parseFloat(values[5]) - Float.parseFloat(values[3]); 
    617539                height /= getSizeY(); 
    618540 
     
    815737        default: 
    816738          // notes for display only 
    817           addGlobalMeta("Note #" + noteCount, n.toString()); 
     739          addGlobalMeta("Note #" + noteIndex, n.toString()); 
    818740      } 
    819741 
     
    932854    else picFiles = null; 
    933855 
     856    status("Reading lookup tables"); 
     857 
     858    lut = new byte[getEffectiveSizeC()][][]; 
     859    for (int channel=0; channel<lut.length; channel++) { 
     860      int plane = getIndex(0, channel, 0); 
     861      String file = 
     862        picFiles == null ? currentId : picFiles[plane % picFiles.length]; 
     863      debug("reading table for C = " + channel + " from " + file, 2); 
     864      RandomAccessInputStream s = new RandomAccessInputStream(file); 
     865      s.order(true); 
     866      readLookupTables(s); 
     867      s.close(); 
     868      if (lut == null) break; 
     869    } 
     870    core[0].indexed = lut != null; 
     871 
    934872    MetadataTools.populatePixels(store, this); 
    935873    MetadataTools.setDefaultCreationDate(store, id, 0); 
     
    969907      } 
    970908    } 
     909  } 
     910 
     911  // -- Helper methods -- 
     912 
     913  /** 
     914   * Read all of the note strings from the given file.  If the 'add' flag is 
     915   * set, the notes will be added to the 'noteStrings' list. 
     916   */ 
     917  private void readNotes(RandomAccessInputStream s, boolean add) 
     918    throws IOException 
     919  { 
     920    s.seek(70); 
     921    int imageLen = getSizeX() * getSizeY(); 
     922    if (picFiles == null) imageLen *= getImageCount(); 
     923    else { 
     924      imageLen *= (getImageCount() / picFiles.length); 
     925    } 
     926    int bpp = FormatTools.getBytesPerPixel(getPixelType()); 
     927    s.skipBytes(bpp * imageLen + 6); 
     928 
     929    boolean notes = true; 
     930    while (notes) { 
     931      // read in note 
     932 
     933      Note n = new Note(); 
     934      n.level = s.readShort(); 
     935      notes = s.readInt() != 0; 
     936      n.num = s.readShort(); 
     937      n.status = s.readShort(); 
     938      n.type = s.readShort(); 
     939      n.x = s.readShort(); 
     940      n.y = s.readShort(); 
     941      n.p = s.readString(80); 
     942 
     943      if (n.type < 0 || n.type >= NOTE_NAMES.length) { 
     944        notes = false; 
     945        brokenNotes = true; 
     946        break; 
     947      } 
     948 
     949      if (!add) continue; 
     950 
     951      // be sure to remove binary data from the note text 
     952      int ndx = n.p.length(); 
     953      for (int i=0; i<n.p.length(); i++) { 
     954        if (n.p.charAt(i) == 0) { 
     955          ndx = i; 
     956          break; 
     957        } 
     958      } 
     959 
     960      n.p = n.p.substring(0, ndx).trim(); 
     961 
     962      String value = n.p.replaceAll("=", ""); 
     963      Vector<String> v = new Vector<String>(); 
     964      StringTokenizer t = new StringTokenizer(value, " "); 
     965      while (t.hasMoreTokens()) { 
     966        String token = t.nextToken().trim(); 
     967        if (token.length() > 0) v.add(token); 
     968      } 
     969      String[] tokens = v.toArray(new String[v.size()]); 
     970      try { 
     971        if (tokens.length > 1) { 
     972          int noteType = Integer.parseInt(tokens[1]); 
     973 
     974          if (noteType == 2 && value.indexOf("AXIS_4") != -1) { 
     975            core[0].sizeZ = 1; 
     976            core[0].sizeT = getImageCount(); 
     977            core[0].orderCertain = true; 
     978          } 
     979        } 
     980      } 
     981      catch (NumberFormatException e) { } 
     982 
     983      // add note to list 
     984      noteStrings.add(n); 
     985    } 
     986  } 
     987 
     988  /** 
     989   * Read all lookup tables from the given file into the 'lut' variable. 
     990   */ 
     991  private void readLookupTables(RandomAccessInputStream s) throws IOException { 
     992    int channel = 0; 
     993    while (channel < lut.length && lut[channel] != null) channel++; 
     994    if (channel >= lut.length) return; 
     995 
     996    readNotes(s, false); 
     997 
     998    // read color tables 
     999    boolean eof = false; 
     1000    int next = 0; 
     1001    while (!eof && channel < lut.length && !brokenNotes) { 
     1002      if (s.getFilePointer() + LUT_LENGTH <= s.length()) { 
     1003        if (lut[channel] == null) { 
     1004          lut[channel] = new byte[3][LUT_LENGTH]; 
     1005        } 
     1006 
     1007        s.read(lut[channel][next++]); 
     1008        if (next == 3) { 
     1009          next = 0; 
     1010          channel++; 
     1011        } 
     1012      } 
     1013      else eof = true; 
     1014      if (eof && channel == 0) { 
     1015        lut = null; 
     1016      } 
     1017    } 
     1018    if (brokenNotes) lut = null; 
    9711019  } 
    9721020 
Note: See TracChangeset for help on using the changeset viewer.