Revision: 21651 http://sourceforge.net/p/jmol/code/21651 Author: hansonr Date: 2017-07-06 07:19:40 +0000 (Thu, 06 Jul 2017) Log Message: ----------- Jmol.___JmolVersion="14.20.1"
new feature: BZ2 compressed file reader -- uses org.apache.tools.bzip2.CBZip2InputStream v. 1.9.6 -- Apache license bug fix: ADF reader not accepting Xx.name atom ids bug fix: ADF reader not accepting Xx.name atom ids bug fix: SMILES generator can show wrong @/@@ or stereochemical type for some allenes and cumulenes bug fix: CIPChirality additional Rules 1b, 4b, and 4c fixes (substituted cubanes; multiple branched branches; 841 lines) Modified Paths: -------------- trunk/Jmol/src/org/apache/tools/bzip2/CBZip2InputStream.java trunk/Jmol/src/org/apache/tools/bzip2/CBZip2InputStreamFactory.java trunk/Jmol/src/org/jmol/adapter/readers/quantum/AdfReader.java trunk/Jmol/src/org/jmol/symmetry/CIPChirality.java trunk/Jmol/src/org/jmol/viewer/ActionManager.java trunk/Jmol/src/org/jmol/viewer/Jmol.properties Modified: trunk/Jmol/src/org/apache/tools/bzip2/CBZip2InputStream.java =================================================================== --- trunk/Jmol/src/org/apache/tools/bzip2/CBZip2InputStream.java 2017-07-06 00:13:14 UTC (rev 21650) +++ trunk/Jmol/src/org/apache/tools/bzip2/CBZip2InputStream.java 2017-07-06 07:19:40 UTC (rev 21651) @@ -116,6 +116,7 @@ * stream to be the first one after the magic. Thus callers have * to skip the first two bytes. Otherwise this constructor will * throw an exception. </p> + * @param in * * @throws IOException * if the stream content is malformed or an I/O error occurs. @@ -161,15 +162,13 @@ setupBlock(); } - /** {@inheritDoc} */ - @Override - public int read() throws IOException { - if (this.in != null) { - return read0(); - } else { - throw new IOException("stream closed"); - } - } + /** {@inheritDoc} */ + @Override + public int read() throws IOException { + if (this.in == null) + throw new IOException("stream closed"); + return read0(); + } /* * (non-Javadoc) @@ -267,17 +266,17 @@ throw new IOException("Empty InputStream"); } } else { - int magic0 = this.in.read(); + int magic0 = readByteAsInt(); if (magic0 == -1) { return false; } - int magic1 = this.in.read(); + int magic1 = readByteAsInt(); if (magic0 != 'B' || magic1 != 'Z') { throw new IOException("Garbage after a valid BZip2 stream"); } } - int magic2 = this.in.read(); + int magic2 = readByteAsInt(); if (magic2 != 'h') { throw new IOException(isFirstStream ? "Stream is not in the BZip2 format" @@ -284,7 +283,7 @@ : "Garbage after a valid BZip2 stream"); } - int blockSize = this.in.read(); + int blockSize = readByteAsInt(); if ((blockSize < '1') || (blockSize > '9')) { throw new IOException("Stream is not BZip2 formatted: illegal " + "blocksize " + (char) blockSize); @@ -298,66 +297,76 @@ return true; } - private void initBlock() throws IOException { - char magic0; - char magic1; - char magic2; - char magic3; - char magic4; - char magic5; + public synchronized int readByteAsInt() throws IOException { + /** + * @j2sNative + * + * return(this.in.readByteAsInt()); + */ + { + return in.read(); + } + } - while (true) { - // Get the block magic bytes. - magic0 = bsGetUByte(); - magic1 = bsGetUByte(); - magic2 = bsGetUByte(); - magic3 = bsGetUByte(); - magic4 = bsGetUByte(); - magic5 = bsGetUByte(); + private void initBlock() throws IOException { + char magic0; + char magic1; + char magic2; + char magic3; + char magic4; + char magic5; - // If isn't end of stream magic, break out of the loop. - if (magic0 != 0x17 || magic1 != 0x72 || magic2 != 0x45 - || magic3 != 0x38 || magic4 != 0x50 || magic5 != 0x90) { - break; - } + while (true) { + // Get the block magic bytes. + magic0 = bsGetUByte(); + magic1 = bsGetUByte(); + magic2 = bsGetUByte(); + magic3 = bsGetUByte(); + magic4 = bsGetUByte(); + magic5 = bsGetUByte(); - // End of stream was reached. Check the combined CRC and - // advance to the next .bz2 stream if decoding concatenated - // streams. - if (complete()) { - return; - } - } + // If isn't end of stream magic, break out of the loop. + if (magic0 != 0x17 || magic1 != 0x72 || magic2 != 0x45 || magic3 != 0x38 + || magic4 != 0x50 || magic5 != 0x90) { + break; + } - if (magic0 != 0x31 || // '1' - magic1 != 0x41 || // ')' - magic2 != 0x59 || // 'Y' - magic3 != 0x26 || // '&' - magic4 != 0x53 || // 'S' - magic5 != 0x59 // 'Y' - ) { - this.currentState = EOF; - throw new IOException("bad block header"); - } else { - this.storedBlockCRC = bsGetInt(); - this.blockRandomised = bsR(1) == 1; + // End of stream was reached. Check the combined CRC and + // advance to the next .bz2 stream if decoding concatenated + // streams. + if (complete()) { + return; + } + } - /** - * Allocate data here instead in constructor, so we do not - * allocate it if the input file is empty. - */ - if (this.data == null) { - this.data = new Data(this.blockSize100k); - } + if (magic0 != 0x31 || // '1' + magic1 != 0x41 || // ')' + magic2 != 0x59 || // 'Y' + magic3 != 0x26 || // '&' + magic4 != 0x53 || // 'S' + magic5 != 0x59 // 'Y' + ) { + this.currentState = EOF; + throw new IOException("bad block header"); + } + this.storedBlockCRC = bsGetInt(); + this.blockRandomised = bsR(1) == 1; - // currBlockNo++; - getAndMoveToFrontDecode(); - - this.crc.initialiseCRC(); - this.currentState = START_BLOCK_STATE; - } + /** + * Allocate data here instead in constructor, so we do not allocate it if + * the input file is empty. + */ + if (this.data == null) { + this.data = new Data(this.blockSize100k); } + // currBlockNo++; + getAndMoveToFrontDecode(); + + this.crc.initialiseCRC(); + this.currentState = START_BLOCK_STATE; + } + private void endBlock() throws IOException { this.computedBlockCRC = this.crc.getFinalCRC(); @@ -415,7 +424,7 @@ if (bsLiveShadow < n) { final InputStream inShadow = this.in; do { - int thech = inShadow.read(); + int thech = readByteAsInt();//inShadow.read(); if (thech < 0) { throw new IOException("unexpected end of stream"); @@ -437,7 +446,7 @@ int bsBuffShadow = this.bsBuff; if (bsLiveShadow < 1) { - int thech = this.in.read(); + int thech = readByteAsInt(); if (thech < 0) { throw new IOException("unexpected end of stream"); @@ -462,6 +471,13 @@ /** * Called by createHuffmanDecodingTables() exclusively. + * @param limit + * @param base + * @param perm + * @param length + * @param minLen + * @param maxLen + * @param alphaSize */ private static void hbCreateDecodeTables(final int[] limit, final int[] base, @@ -588,6 +604,8 @@ /** * Called by recvDecodingTables() exclusively. + * @param alphaSize + * @param nGroups */ private void createHuffmanDecodingTables(final int alphaSize, final int nGroups) { @@ -617,226 +635,217 @@ } } - private void getAndMoveToFrontDecode() throws IOException { - this.origPtr = bsR(24); - recvDecodingTables(); + private void getAndMoveToFrontDecode() throws IOException { + this.origPtr = bsR(24); + recvDecodingTables(); - final InputStream inShadow = this.in; - final Data dataShadow = this.data; - final byte[] ll8 = dataShadow.ll8; - final int[] unzftab = dataShadow.unzftab; - final byte[] selector = dataShadow.selector; - final byte[] seqToUnseq = dataShadow.seqToUnseq; - final char[] yy = dataShadow.getAndMoveToFrontDecode_yy; - final int[] minLens = dataShadow.minLens; - final int[][] limit = dataShadow.limit; - final int[][] base = dataShadow.base; - final int[][] perm = dataShadow.perm; - final int limitLast = this.blockSize100k * 100000; + final InputStream inShadow = this.in; + final Data dataShadow = this.data; + final byte[] ll8 = dataShadow.ll8; + final int[] unzftab = dataShadow.unzftab; + final byte[] selector = dataShadow.selector; + final byte[] seqToUnseq = dataShadow.seqToUnseq; + final char[] yy = dataShadow.getAndMoveToFrontDecode_yy; + final int[] minLens = dataShadow.minLens; + final int[][] limit = dataShadow.limit; + final int[][] base = dataShadow.base; + final int[][] perm = dataShadow.perm; + final int limitLast = this.blockSize100k * 100000; - /* - Setting up the unzftab entries here is not strictly - necessary, but it does save having to do it later - in a separate pass, and so saves a block's worth of - cache misses. - */ - for (int i = 256; --i >= 0;) { - yy[i] = (char) i; - unzftab[i] = 0; - } + /* + Setting up the unzftab entries here is not strictly + necessary, but it does save having to do it later + in a separate pass, and so saves a block's worth of + cache misses. + */ + for (int i = 256; --i >= 0;) { + yy[i] = (char) i; + unzftab[i] = 0; + } - int groupNo = 0; - int groupPos = G_SIZE - 1; - final int eob = this.nInUse + 1; - int nextSym = getAndMoveToFrontDecode0(0); - int bsBuffShadow = this.bsBuff; - int bsLiveShadow = this.bsLive; - int lastShadow = -1; - int zt = selector[groupNo] & 0xff; - int[] base_zt = base[zt]; - int[] limit_zt = limit[zt]; - int[] perm_zt = perm[zt]; - int minLens_zt = minLens[zt]; + int groupNo = 0; + int groupPos = G_SIZE - 1; + final int eob = this.nInUse + 1; + int nextSym = getAndMoveToFrontDecode0(0); + int bsBuffShadow = this.bsBuff; + int bsLiveShadow = this.bsLive; + int lastShadow = -1; + int zt = selector[groupNo] & 0xff; + int[] base_zt = base[zt]; + int[] limit_zt = limit[zt]; + int[] perm_zt = perm[zt]; + int minLens_zt = minLens[zt]; - while (nextSym != eob) { - if ((nextSym == RUNA) || (nextSym == RUNB)) { - int s = -1; + while (nextSym != eob) { + if ((nextSym == RUNA) || (nextSym == RUNB)) { + int s = -1; - for (int n = 1; true; n <<= 1) { - if (nextSym == RUNA) { - s += n; - } else if (nextSym == RUNB) { - s += n << 1; - } else { - break; - } + for (int n = 1; true; n <<= 1) { + if (nextSym == RUNA) { + s += n; + } else if (nextSym == RUNB) { + s += n << 1; + } else { + break; + } - if (groupPos == 0) { - groupPos = G_SIZE - 1; - zt = selector[++groupNo] & 0xff; - base_zt = base[zt]; - limit_zt = limit[zt]; - perm_zt = perm[zt]; - minLens_zt = minLens[zt]; - } else { - groupPos--; - } + if (groupPos == 0) { + groupPos = G_SIZE - 1; + zt = selector[++groupNo] & 0xff; + base_zt = base[zt]; + limit_zt = limit[zt]; + perm_zt = perm[zt]; + minLens_zt = minLens[zt]; + } else { + groupPos--; + } - int zn = minLens_zt; + int zn = minLens_zt; - // Inlined: - // int zvec = bsR(zn); - while (bsLiveShadow < zn) { - final int thech = inShadow.read(); - if (thech >= 0) { - bsBuffShadow = (bsBuffShadow << 8) | thech; - bsLiveShadow += 8; - continue; - } else { - throw new IOException("unexpected end of stream"); - } - } - int zvec = (bsBuffShadow >> (bsLiveShadow - zn)) & ((1 << zn) - 1); - bsLiveShadow -= zn; + // Inlined: + // int zvec = bsR(zn); + while (bsLiveShadow < zn) { + final int thech = readByteAsInt();//inShadow.read(); + if (thech < 0) + throw new IOException("unexpected end of stream"); - while (zvec > limit_zt[zn]) { - zn++; - while (bsLiveShadow < 1) { - final int thech = inShadow.read(); - if (thech >= 0) { - bsBuffShadow = (bsBuffShadow << 8) | thech; - bsLiveShadow += 8; - continue; - } else { - throw new IOException("unexpected end of stream"); - } - } - bsLiveShadow--; - zvec = (zvec << 1) | ((bsBuffShadow >> bsLiveShadow) & 1); - } - nextSym = perm_zt[zvec - base_zt[zn]]; - } + bsBuffShadow = (bsBuffShadow << 8) | thech; + bsLiveShadow += 8; + continue; + } + int zvec = (bsBuffShadow >> (bsLiveShadow - zn)) & ((1 << zn) - 1); + bsLiveShadow -= zn; - final byte ch = seqToUnseq[yy[0]]; - unzftab[ch & 0xff] += s + 1; + while (zvec > limit_zt[zn]) { + zn++; + while (bsLiveShadow < 1) { + final int thech = readByteAsInt();//inShadow.read(); + if (thech < 0) + throw new IOException("unexpected end of stream"); + bsBuffShadow = (bsBuffShadow << 8) | thech; + bsLiveShadow += 8; + continue; + } + bsLiveShadow--; + zvec = (zvec << 1) | ((bsBuffShadow >> bsLiveShadow) & 1); + } + nextSym = perm_zt[zvec - base_zt[zn]]; + } - while (s-- >= 0) { - ll8[++lastShadow] = ch; - } + final byte ch = seqToUnseq[yy[0]]; + unzftab[ch & 0xff] += s + 1; - if (lastShadow >= limitLast) { - throw new IOException("block overrun"); - } - } else { - if (++lastShadow >= limitLast) { - throw new IOException("block overrun"); - } + while (s-- >= 0) { + ll8[++lastShadow] = ch; + } - final char tmp = yy[nextSym - 1]; - unzftab[seqToUnseq[tmp] & 0xff]++; - ll8[lastShadow] = seqToUnseq[tmp]; + if (lastShadow >= limitLast) { + throw new IOException("block overrun"); + } + } else { + if (++lastShadow >= limitLast) { + throw new IOException("block overrun"); + } - /* - This loop is hammered during decompression, - hence avoid native method call overhead of - System.arraycopy for very small ranges to copy. - */ - if (nextSym <= 16) { - for (int j = nextSym - 1; j > 0;) { - yy[j] = yy[--j]; - } - } else { - System.arraycopy(yy, 0, yy, 1, nextSym - 1); - } + final char tmp = yy[nextSym - 1]; + unzftab[seqToUnseq[tmp] & 0xff]++; + ll8[lastShadow] = seqToUnseq[tmp]; - yy[0] = tmp; + /* + This loop is hammered during decompression, + hence avoid native method call overhead of + System.arraycopy for very small ranges to copy. + */ + if (nextSym <= 16) { + for (int j = nextSym - 1; j > 0;) { + yy[j] = yy[--j]; + } + } else { + System.arraycopy(yy, 0, yy, 1, nextSym - 1); + } - if (groupPos == 0) { - groupPos = G_SIZE - 1; - zt = selector[++groupNo] & 0xff; - base_zt = base[zt]; - limit_zt = limit[zt]; - perm_zt = perm[zt]; - minLens_zt = minLens[zt]; - } else { - groupPos--; - } + yy[0] = tmp; - int zn = minLens_zt; + if (groupPos == 0) { + groupPos = G_SIZE - 1; + zt = selector[++groupNo] & 0xff; + base_zt = base[zt]; + limit_zt = limit[zt]; + perm_zt = perm[zt]; + minLens_zt = minLens[zt]; + } else { + groupPos--; + } - // Inlined: - // int zvec = bsR(zn); - while (bsLiveShadow < zn) { - final int thech = inShadow.read(); - if (thech >= 0) { - bsBuffShadow = (bsBuffShadow << 8) | thech; - bsLiveShadow += 8; - continue; - } else { - throw new IOException("unexpected end of stream"); - } - } - int zvec = (bsBuffShadow >> (bsLiveShadow - zn)) & ((1 << zn) - 1); - bsLiveShadow -= zn; + int zn = minLens_zt; - while (zvec > limit_zt[zn]) { - zn++; - while (bsLiveShadow < 1) { - final int thech = inShadow.read(); - if (thech >= 0) { - bsBuffShadow = (bsBuffShadow << 8) | thech; - bsLiveShadow += 8; - continue; - } else { - throw new IOException("unexpected end of stream"); - } - } - bsLiveShadow--; - zvec = (zvec << 1) | ((bsBuffShadow >> bsLiveShadow) & 1); - } - nextSym = perm_zt[zvec - base_zt[zn]]; - } + // Inlined: + // int zvec = bsR(zn); + while (bsLiveShadow < zn) { + final int thech = readByteAsInt();//inShadow.read(); + if (thech < 0) + throw new IOException("unexpected end of stream"); + bsBuffShadow = (bsBuffShadow << 8) | thech; + bsLiveShadow += 8; + continue; } + int zvec = (bsBuffShadow >> (bsLiveShadow - zn)) & ((1 << zn) - 1); + bsLiveShadow -= zn; - this.last = lastShadow; - this.bsLive = bsLiveShadow; - this.bsBuff = bsBuffShadow; + while (zvec > limit_zt[zn]) { + zn++; + while (bsLiveShadow < 1) { + final int thech = readByteAsInt();//inShadow.read(); + if (thech <0) + throw new IOException("unexpected end of stream"); + bsBuffShadow = (bsBuffShadow << 8) | thech; + bsLiveShadow += 8; + continue; + } + bsLiveShadow--; + zvec = (zvec << 1) | ((bsBuffShadow >> bsLiveShadow) & 1); + } + nextSym = perm_zt[zvec - base_zt[zn]]; + } } - private int getAndMoveToFrontDecode0(final int groupNo) - throws IOException { - final InputStream inShadow = this.in; - final Data dataShadow = this.data; - final int zt = dataShadow.selector[groupNo] & 0xff; - final int[] limit_zt = dataShadow.limit[zt]; - int zn = dataShadow.minLens[zt]; - int zvec = bsR(zn); - int bsLiveShadow = this.bsLive; - int bsBuffShadow = this.bsBuff; + this.last = lastShadow; + this.bsLive = bsLiveShadow; + this.bsBuff = bsBuffShadow; + } - while (zvec > limit_zt[zn]) { - zn++; - while (bsLiveShadow < 1) { - final int thech = inShadow.read(); + private int getAndMoveToFrontDecode0(final int groupNo) throws IOException { + final InputStream inShadow = this.in; + final Data dataShadow = this.data; + final int zt = dataShadow.selector[groupNo] & 0xff; + final int[] limit_zt = dataShadow.limit[zt]; + int zn = dataShadow.minLens[zt]; + int zvec = bsR(zn); + int bsLiveShadow = this.bsLive; + int bsBuffShadow = this.bsBuff; - if (thech >= 0) { - bsBuffShadow = (bsBuffShadow << 8) | thech; - bsLiveShadow += 8; - continue; - } else { - throw new IOException("unexpected end of stream"); - } - } - bsLiveShadow--; - zvec = (zvec << 1) | ((bsBuffShadow >> bsLiveShadow) & 1); - } + while (zvec > limit_zt[zn]) { + zn++; + while (bsLiveShadow < 1) { + final int thech = readByteAsInt();//inShadow.read(); - this.bsLive = bsLiveShadow; - this.bsBuff = bsBuffShadow; + if (thech < 0) + throw new IOException("unexpected end of stream"); - return dataShadow.perm[zt][zvec - dataShadow.base[zt][zn]]; + bsBuffShadow = (bsBuffShadow << 8) | thech; + bsLiveShadow += 8; + continue; + } + bsLiveShadow--; + zvec = (zvec << 1) | ((bsBuffShadow >> bsLiveShadow) & 1); } + this.bsLive = bsLiveShadow; + this.bsBuff = bsBuffShadow; + + return dataShadow.perm[zt][zvec - dataShadow.base[zt][zn]]; + } + private void setupBlock() throws IOException { if (this.data == null) { return; @@ -1033,6 +1042,8 @@ * is known. I don't initialize it at construction time to * avoid unnecessary memory allocation when compressing small * files. + * @param length + * @return int array */ final int[] initTT(int length) { int[] ttShadow = this.tt; @@ -1050,6 +1061,7 @@ } + @SuppressWarnings("unused") private static void reportCRCError() throws IOException { // The clean way would be to throw an exception. //throw new IOException("crc error"); Modified: trunk/Jmol/src/org/apache/tools/bzip2/CBZip2InputStreamFactory.java =================================================================== --- trunk/Jmol/src/org/apache/tools/bzip2/CBZip2InputStreamFactory.java 2017-07-06 00:13:14 UTC (rev 21650) +++ trunk/Jmol/src/org/apache/tools/bzip2/CBZip2InputStreamFactory.java 2017-07-06 07:19:40 UTC (rev 21651) @@ -13,7 +13,7 @@ * @throws IOException */ public CBZip2InputStream getStream(InputStream is) throws IOException { - is.read(new byte[2]); + is.read(new byte[2], 0, 2); return new CBZip2InputStream(is); } Modified: trunk/Jmol/src/org/jmol/adapter/readers/quantum/AdfReader.java =================================================================== --- trunk/Jmol/src/org/jmol/adapter/readers/quantum/AdfReader.java 2017-07-06 00:13:14 UTC (rev 21650) +++ trunk/Jmol/src/org/jmol/adapter/readers/quantum/AdfReader.java 2017-07-06 07:19:40 UTC (rev 21651) @@ -161,10 +161,15 @@ if (tokens.length < 5) break; String symbol = tokens[1]; + String name = null; + if (symbol.indexOf(".") >= 0) { + name = symbol; + symbol = symbol.substring(0, symbol.indexOf(".")); + } if (JmolAdapter.getElementNumber(symbol) < 1) nXX++; else - addAtomXYZSymName(tokens, pt0, symbol, null); + addAtomXYZSymName(tokens, pt0, symbol, name); } } Modified: trunk/Jmol/src/org/jmol/symmetry/CIPChirality.java =================================================================== --- trunk/Jmol/src/org/jmol/symmetry/CIPChirality.java 2017-07-06 00:13:14 UTC (rev 21650) +++ trunk/Jmol/src/org/jmol/symmetry/CIPChirality.java 2017-07-06 07:19:40 UTC (rev 21651) @@ -1574,6 +1574,7 @@ * @param isParentBond * @return this */ + @SuppressWarnings("unchecked") CIPAtom create(SimpleNode atom, CIPAtom parent, boolean isAlkene, boolean isDuplicate, boolean isParentBond) { this.id = ++ptID; @@ -1599,9 +1600,9 @@ htPathPoints = new Hashtable<Integer, Integer>(); } else if (parent != null) { rootSubstituent = parent.rootSubstituent; - htPathPoints = rootSubstituent.htPathPoints; + htPathPoints = (Map<Integer, Integer>) ((Hashtable<Integer, Integer>) parent.htPathPoints).clone(); } - this.bsPath = (parent == null ? new BS() : BSUtil.copy(parent.bsPath)); + bsPath = (parent == null ? new BS() : BSUtil.copy(parent.bsPath)); sp2Duplicate = isDuplicate; @@ -1625,15 +1626,15 @@ rootSubstituent.spiroEnd = parent; } else if (bsPath.get(atomIndex)) { isDuplicate = true; - rootDistance = (isParentBond ? parent.sphere : rootSubstituent.htPathPoints.get( + rootDistance = (isParentBond ? parent.sphere : htPathPoints.get( Integer.valueOf(atomIndex)).intValue()); } else { bsPath.set(atomIndex); - rootSubstituent.htPathPoints.put(Integer.valueOf(atomIndex), + htPathPoints.put(Integer.valueOf(atomIndex), Integer.valueOf(rootDistance)); } this.isDuplicate = isDuplicate; - if (Logger.debuggingHigh) { + if (Logger.debugging) { if (sphere < MAX_PATH) // Logger myPath = (parent != null ? parent.myPath + "-" : "") + this; // Logger Logger.info("new CIPAtom " + myPath); @@ -2026,6 +2027,7 @@ // Two duplicates of the same atom are always tied // if they have the same root distance. +// System.out.println("breaking tie for \n" + this.myPath + "\n" + b.myPath); if (isDuplicate && b.isDuplicate && atom == b.atom && rootDistance == b.rootDistance) return TIED; @@ -2066,8 +2068,9 @@ // // The rules require that we first only look at just the atoms, so OOC beats OOH. - if ((score = compareShallowly(b, sphere)) != TIED) + if ((score = compareShallowly(b, sphere)) != TIED) { return score; + } // Phase II -- check deeply using breakTie // @@ -2537,7 +2540,7 @@ } - if (score == A_WINS || score == B_WINS) // Logger + if (Logger.debugging && (score == A_WINS || score == B_WINS)) Logger.info((score == A_WINS ? a : b) + " > " + (score == A_WINS ? b : a) + " by " + reason + "\n"); // Logger // no tie-breaking for Rules 4b or 5 @@ -2547,26 +2550,31 @@ /** * Combine all subpaths - * @param ignore atom to ignore (parent) + * + * @param ignore + * atom to ignore (parent) */ void generateRule4Paths(CIPAtom ignore) { - + getRule4PriorityPaths("", ignore.atom); rootRule4Paths = new Lst<String[]>(); appendRule4Paths(this, new String[3]); - getRule4Counts(rule4Count = new Object[] { null, zero, zero, Integer.valueOf(10000)}); - + getRule4Counts(rule4Count = new Object[] { null, zero, zero, + Integer.valueOf(10000) }); + if (Logger.debugging) { Logger.info("Rule 4b paths for " + this + "=\n"); - for (int i = 0; i < rootRule4Paths.size(); i++) { // Logger - String s = rootRule4Paths.get(i)[0].toString(); // Logger - int prefixLen = rootRule4Paths.get(i)[1].length(); // Logger - while (prefixString.length() < prefixLen) // Logger - prefixString += prefixString; // Logger - Logger.info(prefixString.substring(0, prefixLen) + s.substring(prefixLen) + " " + priorityPath); + for (int i = 0; i < rootRule4Paths.size(); i++) { // Logger + String s = rootRule4Paths.get(i)[0].toString(); // Logger + int prefixLen = rootRule4Paths.get(i)[1].length(); // Logger + while (prefixString.length() < prefixLen) + // Logger + prefixString += prefixString; // Logger + Logger.info(prefixString.substring(0, prefixLen) + + s.substring(prefixLen) + " " + priorityPath); + } + Logger.info(""); } - Logger.info(""); - } } /** @@ -2650,8 +2658,7 @@ private String getRule4ReferenceDescriptor() { if (rule4Count == null) return ("RCM".indexOf(auxChirality) >= 0 ? "R" : "S"); - int nR = ((Integer) rule4Count[1]).intValue(); - int nS = ((Integer) rule4Count[2]).intValue(); + int nR = ((Integer) rule4Count[1]).intValue(), nS = ((Integer) rule4Count[2]).intValue(); return (nR > nS ? "R" : nR < nS ? "S" : "RS"); } @@ -2739,9 +2746,8 @@ } /** - * Creates a list of downstream (higher-sphere) - * auxiliary chirality designators, starting with - * those furthest from the root. + * Creates a list of downstream (higher-sphere) auxiliary chirality + * designators, starting with those furthest from the root. * * @param node1 * first node; sphere 1 @@ -2783,10 +2789,10 @@ nRS++; subRS = ssub; prevIsChiral = true; - } else if (!prevIsChiral && priorities[i] == priorities[i - 1]) { - // two groups have the same priority, and neither has a stereocenter - return "~"; } else { + if (!prevIsChiral && priorities[i] == priorities[i - 1]) + // two groups have the same priority, and neither has a stereocenter + return "~"; prevIsChiral = false; } } Modified: trunk/Jmol/src/org/jmol/viewer/ActionManager.java =================================================================== --- trunk/Jmol/src/org/jmol/viewer/ActionManager.java 2017-07-06 00:13:14 UTC (rev 21650) +++ trunk/Jmol/src/org/jmol/viewer/ActionManager.java 2017-07-06 07:19:40 UTC (rev 21651) @@ -1819,12 +1819,14 @@ case PICKING_LABEL: if (bnd(clickAction, ACTION_pickLabel)) { runScript("set labeltoggle {atomindex=" + atomIndex + "}"); - vwr.setStatusAtomPicked(atomIndex, null, null); + vwr.setStatusAtomPicked(atomIndex, "label picked", null); } return; case PICKING_INVERT_STEREO: - if (bnd(clickAction, ACTION_assignNew)) + if (bnd(clickAction, ACTION_assignNew)) { vwr.invertRingAt(atomIndex, true); + vwr.setStatusAtomPicked(atomIndex, "invert stereo", null); + } return; case PICKING_DELETE_ATOM: if (bnd(clickAction, ACTION_deleteAtom)) { @@ -1991,6 +1993,8 @@ try { BS bs = vwr.getAtomBitSetEval(null, s); vwr.select(bs, false, 0, false); + vwr.setStatusAtomPicked(-1, "selected: " + Escape.eBS(bs), null); + vwr.refresh(3, "selections set"); } catch (Exception e) { // ignore Modified: trunk/Jmol/src/org/jmol/viewer/Jmol.properties =================================================================== --- trunk/Jmol/src/org/jmol/viewer/Jmol.properties 2017-07-06 00:13:14 UTC (rev 21650) +++ trunk/Jmol/src/org/jmol/viewer/Jmol.properties 2017-07-06 07:19:40 UTC (rev 21651) @@ -61,9 +61,13 @@ new feature: BZ2 compressed file reader -- uses org.apache.tools.bzip2.CBZip2InputStream v. 1.9.6 -- Apache license + +bug fix: ADF reader not accepting Xx.name atom ids +bug fix: ADF reader not accepting Xx.name atom ids + bug fix: SMILES generator can show wrong @/@@ or stereochemical type for some allenes and cumulenes -bug fix: CIPChirality additional Rule 4b and 4c fixes +bug fix: CIPChirality additional Rules 1b, 4b, and 4c fixes (substituted cubanes; multiple branched branches; 841 lines) JmolVersion="14.19.1" // 2017.06.25 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ Jmol-commits mailing list Jmol-commits@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jmol-commits