Revision: 20092 http://sourceforge.net/p/jmol/code/20092 Author: hansonr Date: 2014-11-08 17:40:11 +0000 (Sat, 08 Nov 2014) Log Message: ----------- Jmol.___JmolVersion="14.3.8_2014.11.08"
new feature: CAPTURE "filename0000.png" -- captures set of PNG files -- 0000 is not required new feature: CAPTURE "filename0000.gif" -- captures set of GIF files -- 0000 IS required in order to distinguish this from animated GIF code: code clean-up in GData, Graphics3D, and Export3D code: modifications to GIF writer. Not really satisfying; still using HSL code: PDB reader CONECT efficiency bug fix: PDB reader limited to 20 connections per atom Modified Paths: -------------- trunk/Jmol/src/javajs/img/GifEncoder.java trunk/Jmol/src/javajs/util/OC.java trunk/Jmol/src/org/jmol/adapter/readers/pdb/PdbReader.java trunk/Jmol/src/org/jmol/scriptext/CmdExt.java trunk/Jmol/src/org/jmol/viewer/Jmol.properties trunk/Jmol/src/org/jmol/viewer/OutputManager.java Modified: trunk/Jmol/src/javajs/img/GifEncoder.java =================================================================== --- trunk/Jmol/src/javajs/img/GifEncoder.java 2014-11-07 13:23:58 UTC (rev 20091) +++ trunk/Jmol/src/javajs/img/GifEncoder.java 2014-11-08 17:40:11 UTC (rev 20092) @@ -120,6 +120,69 @@ int[] red, green, blue; int[] indexes; + /** + * we allow for animated GIF by being able to re-enter the code with different + * parameters held in params + * + * + */ + @Override + protected void setParams(Map<String, Object> params) { + this.params = params; + Integer ic = (Integer) params.get("transparentColor"); + if (ic == null) { + ic = (Integer) params.get("backgroundColor"); + if (ic != null) + backgroundColor = ic.intValue(); + } else { + backgroundColor = ic.intValue(); + isTransparent = true; + } + + //floydSteinberg = false; + + logging = true; + + interlaced = (Boolean.TRUE == params.get("interlaced")); + if (interlaced + || params.containsKey("captureRootExt") // file0000.gif + || !params.containsKey("captureMode")) // animated gif + return; + try { + byteCount = ((Integer) params.get("captureByteCount")).intValue(); + } catch (Exception e) { + // ignore + } + int imode = "maec".indexOf(((String) params.get("captureMode")).substring( + 0, 1)); + + if (logging) + System.out.println("GIF capture mode " + imode); + switch (imode) { + case 0: //"movie" + params.put("captureMode", "add"); + addImage = false; + addTrailer = false; + break; + case 1: // add + addHeader = false; + addTrailer = false; + int fps = Math.abs(((Integer) params.get("captureFps")).intValue()); + delayTime100ths = (fps == 0 ? 0 : 100 / fps); + looping = (Boolean.FALSE != params.get("captureLooping")); + break; + case 2: // end + addHeader = false; + addImage = false; + break; + case 3: // cancel + addHeader = false; + addImage = false; + out.cancel(); + break; + } + } + private class ColorItem { int rgb; @@ -432,66 +495,6 @@ } } - /** - * we allow for animated GIF by being able to re-enter the code with different - * parameters held in params - * - * - */ - @Override - protected void setParams(Map<String, Object> params) { - this.params = params; - Integer ic = (Integer) params.get("transparentColor"); - if (ic == null) { - ic = (Integer) params.get("backgroundColor"); - if (ic != null) - backgroundColor = ic.intValue(); - } else { - backgroundColor = ic.intValue(); - isTransparent = true; - } - - //floydSteinberg = false; - - logging = true; - - interlaced = (Boolean.TRUE == params.get("interlaced")); - if (interlaced || !params.containsKey("captureMode")) - return; - try { - byteCount = ((Integer) params.get("captureByteCount")).intValue(); - } catch (Exception e) { - // ignore - } - int imode = "maec".indexOf(((String) params.get("captureMode")).substring( - 0, 1)); - - if (logging) - System.out.println("GIF capture mode " + imode); - switch (imode) { - case 0: //"movie" - params.put("captureMode", "add"); - addImage = false; - addTrailer = false; - break; - case 1: // add - addHeader = false; - addTrailer = false; - int fps = Math.abs(((Integer) params.get("captureFps")).intValue()); - delayTime100ths = (fps == 0 ? 0 : 100 / fps); - looping = (Boolean.FALSE != params.get("captureLooping")); - break; - case 2: // end - addHeader = false; - addImage = false; - break; - case 3: // cancel - addHeader = false; - addImage = false; - out.cancel(); - break; - } - } /* float RFACTOR = 3.6f; float DELTA = 0.001f; Modified: trunk/Jmol/src/javajs/util/OC.java =================================================================== --- trunk/Jmol/src/javajs/util/OC.java 2014-11-07 13:23:58 UTC (rev 20091) +++ trunk/Jmol/src/javajs/util/OC.java 2014-11-08 17:40:11 UTC (rev 20092) @@ -72,6 +72,7 @@ os = null; } this.os = os; + System.out.println("OC " + fileName); isLocalFile = (fileName != null && !(fileName.startsWith("http://") || fileName .startsWith("https://"))); if (asWriter && !isBase64 && os != null) @@ -147,6 +148,8 @@ { if (os instanceof FileOutputStream) { os.close(); + System.out.println("OC2 " + fileName); + os = new FileOutputStream(fileName); } else { os = null; @@ -259,10 +262,14 @@ } else if (os != null) { os.flush(); os.close(); + System.out.println("OC3 " + fileName); + } if (os0 != null && isCanceled) { os0.flush(); os0.close(); + System.out.println("OC4 " + fileName); + } } catch (Exception e) { // ignore closing issues Modified: trunk/Jmol/src/org/jmol/adapter/readers/pdb/PdbReader.java =================================================================== --- trunk/Jmol/src/org/jmol/adapter/readers/pdb/PdbReader.java 2014-11-07 13:23:58 UTC (rev 20091) +++ trunk/Jmol/src/org/jmol/adapter/readers/pdb/PdbReader.java 2014-11-08 17:40:11 UTC (rev 20092) @@ -1103,6 +1103,36 @@ private boolean haveDoubleBonds; + // ancient provisions: + // - must check for pre-2000 format with hydrogen bonds + // - salt bridges are totally ignored + //7 - 11 source + //12 - 16 target + //17 - 21 target + //22 - 26 target + //27 - 31 target + //32 - 36 Hydrogen bond + //37 - 41 Hydrogen bond + //42 - 46 Salt bridge + //47 - 51 Hydrogen bond + //52 - 56 Hydrogen bond + //57 - 61 Salt bridge + //FORMAT (6A1,11I5) + //Note: Serial numbers are identical to those in cols. 7-11 of the appropriate ATOM/ + //HETATM records, and connectivity entries correspond to these serial numbers. A + //second CONECT record, with the same serial number in cols. 7-11, may be used + //if necessary. Either all or none of the covalent connectivity of an atom must be + //specified, and if hydrogen bonding is specified the covalent connectivity is + //included also. + //The occurrence of a negative atom serial number on a CONECT record denotes + //that a translationally equivalent copy (see TVECT records) of the target atom specified + //is linked to the origin atom of the record. + + // 0 1 2 3 4 5 6 + // 012345678901234567890123456789012345678901234567890123456789012 + // CONECT 15 14 493 1BNA 635 + + private void conect() { if (sbConect == null) { sbConect = new SB(); @@ -1110,28 +1140,25 @@ } else { sb.setLength(0); } - int sourceSerial = -1; - sourceSerial = getSerial(6, 11); + int sourceSerial = getSerial(6, 11); if (sourceSerial < 0) return; int order = 1; - // skip ancient salt bridges - int pt1 = Math.min(line.trim().length(), 52); + int pt1 = line.trim().length(); + if (pt1 > 56) // ancient full line; ignore final salt bridge + pt1 = line.substring(0, 56).trim().length(); for (int pt = 11; pt < pt1; pt += 5) { switch (pt) { case 31: order = JmolAdapter.ORDER_HBOND; break; case 41: - // old salt bridge + // ancient salt bridge continue; } int targetSerial = getSerial(pt, pt + 5); - if (targetSerial < 0) { - if (pt <= 31) // no hbonds -- get out of here - break; + if (targetSerial < 0) // ancient gap in numbers continue; - } boolean isDoubleBond = (sourceSerial == lastSourceSerial && targetSerial == lastTargetSerial); if (isDoubleBond) haveDoubleBonds = true; @@ -1161,43 +1188,40 @@ sbConect.appendSB(sb); } - /* - 1 2 3 - 0123456789012345678901234567890123456 - HELIX 1 H1 ILE 7 LEU 18 - HELIX 2 H2 PRO 19 PRO 19 - HELIX 3 H3 GLU 23 TYR 29 - HELIX 4 H4 THR 30 THR 30 - SHEET 1 S1 2 THR 2 CYS 4 - SHEET 2 S2 2 CYS 32 ILE 35 - SHEET 3 S3 2 THR 39 PRO 41 - TURN 1 T1 GLY 42 TYR 44 - - HELIX 1 H1 ILE A 7 PRO A 19 - HELIX 2 H2 GLU A 23 THR A 30 - SHEET 1 S1 0 CYS A 3 CYS A 4 - SHEET 2 S2 0 CYS A 32 ILE A 35 - - HELIX 113 113 ASN H 307 ARG H 327 1 21 - SHEET 1 A 6 ASP A 77 HIS A 80 0 - SHEET 2 A 6 GLU A 47 ILE A 51 1 N ILE A 48 O ASP A 77 - SHEET 3 A 6 ARG A 22 ILE A 26 1 N VAL A 23 O GLU A 47 - - -TYPE OF HELIX CLASS NUMBER (COLUMNS 39 - 40) --------------------------------------------------------------- -Right-handed alpha (default) 1 -Right-handed omega 2 -Right-handed pi 3 -Right-handed gamma 4 -Right-handed 310 5 -Left-handed alpha 6 -Left-handed omega 7 -Left-handed gamma 8 -27 ribbon/helix 9 -Polyproline 10 - - */ + // 0 1 2 3 + // 0123456789012345678901234567890123456 + // HELIX 1 H1 ILE 7 LEU 18 + // HELIX 2 H2 PRO 19 PRO 19 + // HELIX 3 H3 GLU 23 TYR 29 + // HELIX 4 H4 THR 30 THR 30 + // SHEET 1 S1 2 THR 2 CYS 4 + // SHEET 2 S2 2 CYS 32 ILE 35 + // SHEET 3 S3 2 THR 39 PRO 41 + // TURN 1 T1 GLY 42 TYR 44 + // + // HELIX 1 H1 ILE A 7 PRO A 19 + // HELIX 2 H2 GLU A 23 THR A 30 + // SHEET 1 S1 0 CYS A 3 CYS A 4 + // SHEET 2 S2 0 CYS A 32 ILE A 35 + // + // HELIX 113 113 ASN H 307 ARG H 327 1 21 + // SHEET 1 A 6 ASP A 77 HIS A 80 0 + // SHEET 2 A 6 GLU A 47 ILE A 51 1 N ILE A 48 O ASP A 77 + // SHEET 3 A 6 ARG A 22 ILE A 26 1 N VAL A 23 O GLU A 47 + // + // + //TYPE OF HELIX CLASS NUMBER (COLUMNS 39 - 40) + //-------------------------------------------------------------- + //Right-handed alpha (default) 1 + //Right-handed omega 2 + //Right-handed pi 3 + //Right-handed gamma 4 + //Right-handed 310 5 + //Left-handed alpha 6 + //Left-handed omega 7 + //Left-handed gamma 8 + //27 ribbon/helix 9 + //Polyproline 10 private void structure() { STR structureType = STR.NONE; Modified: trunk/Jmol/src/org/jmol/scriptext/CmdExt.java =================================================================== --- trunk/Jmol/src/org/jmol/scriptext/CmdExt.java 2014-11-07 13:23:58 UTC (rev 20091) +++ trunk/Jmol/src/org/jmol/scriptext/CmdExt.java 2014-11-08 17:40:11 UTC (rev 20092) @@ -477,6 +477,8 @@ showString("Cannot capture on this platform"); return; } + Map<String, Object> params = vwr.captureParams; + String type = (params == null ? "GIF" : (String) params.get("type")); float endTime = 10; // ten seconds by default int mode = 0; int slen = e.slen; @@ -484,7 +486,6 @@ if (isTransparent) slen--; String fileName = ""; - Map<String, Object> params = vwr.captureParams; boolean looping = !vwr.am.animationReplayMode.name().equals("ONCE"); int i = 1; int tok = tokAt(i); @@ -495,12 +496,22 @@ mode = T.end; break; } - if (fileName.toLowerCase().endsWith(".gift")) { + String lc = fileName.toLowerCase(); + if (lc.endsWith(".gift") || lc.endsWith(".pngt")) { isTransparent = true; fileName = fileName.substring(0, fileName.length() - 1); + lc = fileName.toLowerCase(); + } else if (!lc.endsWith(".gif") && !lc.contains(".png")) { + fileName += ".gif"; } - if (!fileName.toLowerCase().endsWith(".gif")) - fileName += ".gif"; + if (lc.endsWith(".png")) { + if (!lc.endsWith("0.png")) + fileName = fileName.substring(0, fileName.length() - 4) + "0000.png"; + type = "PNG"; + } else { + type = "GIF"; + } + boolean streaming = (fileName.indexOf("0000.") != fileName.lastIndexOf(".") - 4); boolean isRock = false; switch (tokAt(i)) { case T.rock: @@ -544,12 +555,15 @@ return; mode = T.movie; params = new Hashtable<String, Object>(); - if (!looping) - showString(GT.o(GT._("Note: Enable looping using {0}"), - new Object[] { "ANIMATION MODE LOOP" })); int fps = vwr.getInt(T.animationfps); - showString(GT.o(GT._("Animation delay based on: {0}"), - new Object[] { "ANIMATION FPS " + fps })); + if (streaming) { + params.put("streaming", Boolean.TRUE); + if (!looping) + showString(GT.o(GT._("Note: Enable looping using {0}"), + new Object[] { "ANIMATION MODE LOOP" })); + showString(GT.o(GT._("Animation delay based on: {0}"), + new Object[] { "ANIMATION FPS " + fps })); + } params.put("captureFps", Integer.valueOf(fps)); break; case T.end: @@ -567,7 +581,7 @@ } if (chk || params == null) return; - params.put("type", "GIF"); + params.put("type", type); Integer c = Integer.valueOf(vwr.getBackgroundArgb()); params.put("backgroundColor", c); if (isTransparent) Modified: trunk/Jmol/src/org/jmol/viewer/Jmol.properties =================================================================== --- trunk/Jmol/src/org/jmol/viewer/Jmol.properties 2014-11-07 13:23:58 UTC (rev 20091) +++ trunk/Jmol/src/org/jmol/viewer/Jmol.properties 2014-11-08 17:40:11 UTC (rev 20092) @@ -14,10 +14,17 @@ TODO: design and implement sidechain mutation -- MUTATE command ? TODO: remove HTML5 dependency on synchronous file loading (check SCRIPT command for problems) -TODO: CAPTURE to PNG -Jmol.___JmolVersion="14.3.8_2014.11.07" +Jmol.___JmolVersion="14.3.8_2014.11.08" +new feature: CAPTURE "filename0000.png" + -- captures set of PNG files + -- 0000 is not required + +new feature: CAPTURE "filename0000.gif" + -- captures set of GIF files + -- 0000 IS required in order to distinguish this from animated GIF + code: code clean-up in GData, Graphics3D, and Export3D code: modifications to GIF writer. Not really satisfying; still using HSL code: PDB reader CONECT efficiency Modified: trunk/Jmol/src/org/jmol/viewer/OutputManager.java =================================================================== --- trunk/Jmol/src/org/jmol/viewer/OutputManager.java 2014-11-07 13:23:58 UTC (rev 20091) +++ trunk/Jmol/src/org/jmol/viewer/OutputManager.java 2014-11-08 17:40:11 UTC (rev 20092) @@ -408,12 +408,8 @@ quality)); if (fileName == null) return null; - int ptDot = fileName.indexOf("."); - if (ptDot < 0) - ptDot = fileName.length(); - - String froot = fileName.substring(0, ptDot); - String fext = fileName.substring(ptDot); + String[] rootExt = new String[2]; + getRootExt(fileName, rootExt, 0); SB sb = new SB(); if (bsFrames == null) { vwr.tm.vibrationOn = true; @@ -421,7 +417,7 @@ for (int i = 0; i < nVibes; i++) { for (int j = 0; j < 20; j++) { vwr.tm.setVibrationT(j / 20f + 0.2501f); - if (!writeFrame(++n, froot, fext, params, sb)) + if (!writeFrame(++n, rootExt, params, sb)) return "ERROR WRITING FILE SET: \n" + info; } } @@ -430,7 +426,7 @@ for (int i = bsFrames.nextSetBit(0); i >= 0; i = bsFrames .nextSetBit(i + 1)) { vwr.setCurrentModelIndex(i); - if (!writeFrame(++n, froot, fext, params, sb)) + if (!writeFrame(++n, rootExt, params, sb)) return "ERROR WRITING FILE SET: \n" + info; } } @@ -439,6 +435,23 @@ return info + "\n" + n + " files created"; } + private static Object getRootExt(String fileName, String[] rootExt, int n) { + if (fileName == null) { + fileName = "0000" + n; + return rootExt[0] + fileName.substring(fileName.length() - 4) + + rootExt[1]; + } + int ptDot = fileName.lastIndexOf("."); + if (ptDot < 0) + ptDot = fileName.length(); + String froot = fileName.substring(0, ptDot); + if (froot.endsWith("0")) + froot = PT.trim(froot, "0"); + rootExt[0] = froot; + rootExt[1] = fileName.substring(ptDot); + return rootExt; + } + private String setFullPath(Map<String, Object> params, String fileName) { String[] fullPath = (String[]) params.get("fullPath"); if (fullPath != null) @@ -561,11 +574,12 @@ return msg; } - private boolean writeFrame(int n, String froot, String fext, + private boolean writeFrame(int n, String[] rootExt, Map<String, Object> params, SB sb) { - String fileName = "0000" + n; - fileName = setFullPath(params, froot - + fileName.substring(fileName.length() - 4) + fext); + String fileName = (String) getRootExt(null, rootExt, n); + fileName = setFullPath(params, fileName); + if (fileName == null) + return false; String msg = handleOutputToFile(params, false); vwr.scriptEcho(msg); sb.append(msg).append("\n"); @@ -625,7 +639,6 @@ if (captureMode != null) { doCheck = false; // will be checked later mustRender = false; - type = "GIF"; } if (doCheck) fileName = getOutputFileNameFromDialog(fileName, quality); @@ -651,8 +664,8 @@ String[] scripts = (String[]) params.get("scripts"); if (scripts != null && type.equals("ZIP")) type = "ZIPALL"; - OC out = getOutputChannel(fileName, null); - sret = createZipSet(text, scripts, type.equals("ZIPALL"), out, null); + sret = createZipSet(text, scripts, type.equals("ZIPALL"), + getOutputChannel(fileName, null), null); } else if (type.equals("SCENE")) { sret = createSceneSet(fileName, text, width, height); } else { @@ -660,50 +673,82 @@ // both Jmol application and applet return null byte[] bytes = (byte[]) params.get("bytes"); // String return here - sret = vwr.sm.createImage(fileName, type, text, bytes, - quality); + sret = vwr.sm.createImage(fileName, type, text, bytes, quality); if (sret == null) { + boolean createImage = true; // allow Jmol to do it - String msg = null; + String captureMsg = null; if (captureMode != null) { OC out = null; Map<String, Object> cparams = vwr.captureParams; int imode = "ad on of en ca mo ".indexOf(captureMode .substring(0, 2)); // 0 3 6 9 12 15 - switch (imode) { - case 15: - if (cparams != null) + String[] rootExt; + if (imode == 15) {// movie -- start up + if (cparams != null && cparams.containsKey("outputChannel")) ((OC) cparams.get("outputChannel")).closeChannel(); - out = getOutputChannel(localName, null); - if (out == null) { - sret = msg = "ERROR: capture canceled"; + boolean streaming = params.containsKey("streaming"); + if (streaming + && (out = getOutputChannel(localName, null)) == null) { + sret = captureMsg = "ERROR: capture canceled"; vwr.captureParams = null; } else { - localName = out.getFileName(); - msg = type + "_STREAM_OPEN " + localName; vwr.captureParams = params; - params.put("captureFileName", localName); - params.put("captureCount", Integer.valueOf(1)); - params.put("captureMode", "movie"); + if (params.containsKey("captureRootExt")) { + imode = 0; // add + } else { + if (out != null) + localName = out.getFileName(); + params.put("captureFileName", localName); + if (streaming) { + captureMsg = type + "_STREAM_OPEN " + localName; + params.put("captureMode", "movie"); + } else { + rootExt = new String[2]; + params.put("captureRootExt", + getRootExt(localName, rootExt, 0)); + localName = (String) getRootExt(null, rootExt, 1); + imode = -1; // ignore + cparams = params; + createImage = false; + } + } + if (!params.containsKey("captureCount")) + params.put("captureCount", Integer.valueOf(0)); } - break; - default: + } + if (imode >= 0 && imode != 15) { if (cparams == null) { - sret = msg = "ERROR: capture not active"; + sret = captureMsg = "ERROR: capture not active"; } else { params = cparams; switch (imode) { default: - sret = msg = "ERROR: CAPTURE MODE=" + captureMode + "?"; + sret = captureMsg = "ERROR: CAPTURE MODE=" + captureMode + + "?"; break; case 0: //add: if (Boolean.FALSE == params.get("captureEnabled")) { - sret = msg = "capturing OFF; use CAPTURE ON/END/CANCEL to continue"; + sret = captureMsg = "capturing OFF; use CAPTURE ON/END/CANCEL to continue"; } else { - int count = getInt(params, "captureCount", 1); + int count = getInt(params, "captureCount", 0); params.put("captureCount", Integer.valueOf(++count)); - msg = type + "_STREAM_ADD " + count; + if (count == 10) + System.out.println("outman 10"); + + if ((rootExt = (String[]) params.get("captureRootExt")) != null) { + localName = (String) getRootExt(null, rootExt, count); + captureMsg = null; + createImage = true; + //out = (OC) params.get("outputChannel"); + //if (out != null) + // out.closeChannel(); + //out = getOutputChannel(localName, null); + //out = null; + } else { + captureMsg = type + "_STREAM_ADD " + count; + } } break; case 3: //on: @@ -722,37 +767,49 @@ params = cparams; params.put("captureMode", captureMode); fileName = (String) params.get("captureFileName"); - msg = type + "_STREAM_" + captureMsg = type + "_STREAM_" + (captureMode.equals("end") ? "CLOSE " : "CANCEL ") - + params.get("captureFileName"); + + fileName; vwr.captureParams = null; params.put("captureMsg", GT._("Capture") + ": " + (captureMode.equals("cancel") ? GT._("canceled") : GT.o(GT._("{0} saved"), fileName))); + if (params.containsKey("captureRootExt")) + createImage = false; + break; } - break; } - break; } - if (out != null) + if (createImage && out != null) params.put("outputChannel", out); } - if (localName != null) - params.put("fileName", localName); - if (sret == null) - sret = writeToOutputChannel(params); - vwr.sm.createImage(sret, type, null, null, quality); - if (msg != null) - vwr.showString(msg + " (" + params.get("captureByteCount") - + " bytes)", false); + if (createImage) { + if (localName != null) + params.put("fileName", localName); + if (sret == null) + sret = writeToOutputChannel(params); + vwr.sm.createImage(sret, type, null, null, quality); + if (captureMode != null) { + if (captureMsg == null) + captureMsg = sret; + else + captureMsg += " (" + + params + .get(params.containsKey("captureByteCount") ? "captureByteCount" + : "byteCount") + " bytes)"; + } + } + if (captureMsg != null) { + vwr.showString(captureMsg, false); + } } } } catch (Throwable er) { - //er.printStackTrace(); - Logger.error(vwr.setErrorMessage(sret = "ERROR creating image??: " - + er, null)); + er.printStackTrace(); + Logger.error(vwr.setErrorMessage(sret = "ERROR creating image??: " + er, + null)); } finally { vwr.creatingImage = false; if (quality != Integer.MIN_VALUE) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ _______________________________________________ Jmol-commits mailing list Jmol-commits@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jmol-commits