准备用JAVA完成对光谱的读取,并寻找相似集。下午开始,就卡在光谱的读取中,郁闷了一个下午。以前用MATLAB写过读取光谱的代码(FIT文件格式解析及MATLAB读取程序),也用C++写过,但是觉得C++以前一个字节一个自己的读取过于麻烦,所以对于JAVA的,先找找是不是有读取fits文件的包。没想到还找到了:Java Library for access to FITS files 。但是,后来问题来了:
开始我用v2..3版本的fits数据,读取文件都没问题,对于关键字的读取很顺利。后来想着现在的pipeline都是2.6版本的了,所以还是重新下载了新版本的数据,但是问题来了,一直显示不是fits文件。但是我用fv打开一切都正常。后来下了dr8的数据,也没发现问题,说明这个包的兼容性还是可以的,但是不知道为什么出现问题。
首先,我想到是不是因为数据的事,后来重新下载了2.6版本的其他数据,测试,还是一样的问题。而且用fv能正常打开,所以数据的问题应该可以排除。
没办法,只能从包里找问题了,因为pipeline跑出来的数据是没法重新修改的,否则这么大的数据,是整个工程的事。幸好这个Library给出了source文件,把source文件加载了,然后一步一步的调试,F11,F5,F6,F8,System.out.println, 找了很久,跟踪了很久,终于发现问题了。
肯定是这个keyword出了问题,但是没有明显的差别啊。后来跟踪到源代码的异常处理后发现问题的关键所在:
public FitsKeyword(byte[] card) throws FitsException { int idx = 0; // index in FITS card int idx_last = 0; // last index of value field int idx_comm_first = 0; // first index of comment field // if card is null or too short - add spaces if (card == null || card.length < Fits.CARD) { byte[] pc = new byte[Fits.CARD]; int n = 0; while (n < card.length) { pc[n] = card[n]; n++; } while (n < Fits.CARD) pc[n++] = SPACE; card = pc; } if ((card[0] != SPACE) && (card[0] != MINUS) && (card[0] != UNDERSCORE) && ((card[0] < A) || (Z < card[0])) ) { throw new FitsException("Illegal character", FitsException.KEYWORD); }
终于找到Bug了,很开心,呵呵,虽然问题很小很小,但是过程是美好的,也进一步对JAVA的调试,包的导入有了更好的理解。另外,在Source中发现这样一段代码:
try { int n = 0; while (true) { //System.out.println(kw.getString()); for (int k=0; k<Fits.CARD; k++) { line[k] = record[n++]; } kw = new FitsKeyword(line); keywords.add(kw); if (Fits.RECORD <= n) { file.readFully(record, 0, Fits.RECORD); n = 0; } } } catch (IOException e) { throw new FitsException("Cannot read header", FitsException.HEADER); } catch (FitsException e) { if (e.getType() != FitsException.ENDCARD) { throw new FitsException("Bad FITS keyword", FitsException.HEADER); } }
总结:遇到问题,一定要理性的去分析,排除原因,一步一步调试,和C++一样,要熟练是使用调试。另外有时间多看看别人写的源码,真的能有很多启发。