Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

r""" 

Interface for extracting data and generating images from Jmol readable files. 

 

JmolData is a no GUI version of Jmol useful for extracting data from files Jmol 

reads and for generating image files. 

 

AUTHORS: 

 

- Jonathan Gutow (2012-06-14): complete doctest coverage 

- Jonathan Gutow (2012-03-21): initial version 

""" 

 

#******************************************************************************* 

# Copyright (C) 2012 Jonathan Gutow (gutow@uwosh.edu) 

# 

# Distributed under the terms of the GNU General Public License (GPL) 

# as published by the Free Software Foundation; either version 2 of 

# the License, or (at your option) any later version. 

# http://www.gnu.org/licenses/ 

#******************************************************************************* 

from __future__ import print_function 

 

from sage.structure.sage_object import SageObject 

 

from sage.env import SAGE_LOCAL 

from sage.misc.temporary_file import tmp_filename 

from sage.cpython.string import bytes_to_str 

 

import os 

import re 

import subprocess 

 

class JmolData(SageObject): 

r""" 

.. todo:: 

 

Create an animated image file (GIF) if spin is on and put data 

extracted from a file into a variable/string/structure to return 

""" 

def __init__(self): 

""" 

EXAMPLES: 

 

Create a JmolData object:: 

 

sage: from sage.interfaces.jmoldata import JmolData 

sage: JData = JmolData() 

""" 

pass 

 

def is_jvm_available(self): 

""" 

Returns True if the Java Virtual Machine is available and False if not. 

 

EXAMPLES: 

 

Check that it returns a boolean:: 

 

sage: from sage.interfaces.jmoldata import JmolData 

sage: JData = JmolData() 

sage: type(JData.is_jvm_available()) 

<... 'bool'> 

""" 

try: 

version = bytes_to_str(subprocess.check_output(['java', '-version'], stderr=subprocess.STDOUT)) 

except (subprocess.CalledProcessError, OSError): 

return False 

 

java_version = re.search('version.*([1][.][789]|"\d+")', version) 

return java_version is not None 

 

def export_image(self, 

targetfile, 

datafile, #name (path) of data file Jmol can read or script file telling it what to read or load 

datafile_cmd='script', #"script" or "load" 

image_type ='PNG', #PNG, JPG, GIF 

figsize=5, 

**kwds): 

r""" 

This executes JmolData.jar to make an image file. 

 

INPUT: 

 

- targetfile -- the full path to the file where the image 

should be written. 

 

- datafile -- full path to the data file Jmol can read or 

text of a script telling Jmol what to read or load. 

If it is a script and the platform is cygwin, the filenames in 

the script should be in native windows format. 

 

- datafile_cmd -- (default ``'script'``) ``'load'`` or ``'script'`` 

should be ``"load"`` for a data file. 

 

- image_type -- (default ``"PNG"``) ``'PNG'`` ``'JPG'`` or ``'GIF'`` 

 

- figsize -- number (default 5) equal to (pixels/side)/100 

 

OUTPUT: 

 

Image file, .png, .gif or .jpg (default .png) 

 

.. note:: 

 

Examples will generate an error message if a functional Java Virtual Machine (JVM) 

is not installed on the machine the Sage instance is running on. 

 

.. warning:: 

 

Programmers using this module should check that the JVM is 

available before making calls to avoid the user getting 

error messages. Check for the JVM using the function 

:meth:`is_jvm_available`, which returns True if a JVM is available. 

 

EXAMPLES: 

 

Use Jmol to load a pdb file containing some DNA from a web data 

base and make an image of the DNA. If you execute this in the 

notebook, the image will appear in the output cell:: 

 

sage: from sage.interfaces.jmoldata import JmolData 

sage: JData = JmolData() 

sage: script = "load =1lcd;display DNA;moveto 0.0 { -473 -713 -518 59.94} 100.0 0.0 0.0 {21.17 26.72 27.295} 27.544636 {0.0 0.0 0.0} -25.287832 64.8414 0.0;" 

sage: testfile = tmp_filename(ext="DNA.png") 

sage: JData.export_image(targetfile=testfile,datafile=script,image_type="PNG") # optional -- java internet 

sage: print(os.path.exists(testfile)) # optional -- java internet 

True 

 

Use Jmol to save an image of a 3-D object created in Sage. 

This method is used internally by plot3d to generate static images. 

This example doesn't have correct scaling:: 

 

sage: from sage.interfaces.jmoldata import JmolData 

sage: JData = JmolData() 

sage: D = dodecahedron() 

sage: from sage.misc.misc import SAGE_TMP 

sage: archive_name = os.path.join(SAGE_TMP, "archive.jmol.zip") 

sage: D.export_jmol(archive_name) #not scaled properly...need some more steps. 

sage: archive_native = archive_name 

sage: import sys 

sage: if sys.platform == 'cygwin': 

....: from subprocess import check_output, STDOUT 

....: archive_native = check_output(['cygpath', '-w', archive_native], 

....: stderr=STDOUT).decode('utf-8').rstrip() 

sage: script = 'set defaultdirectory "{0}"\n script SCRIPT\n'.format(archive_native) 

sage: testfile = os.path.join(SAGE_TMP, "testimage.png") 

sage: JData.export_image(targetfile=testfile, datafile=script, image_type="PNG") # optional -- java 

sage: print(os.path.exists(testfile)) # optional -- java 

True 

""" 

# Set up paths, file names and scripts 

jmolpath = os.path.join(SAGE_LOCAL, "share", "jmol", "JmolData.jar") 

target_native = targetfile 

import sys 

if sys.platform == 'cygwin': 

jmolpath = bytes_to_str(subprocess.check_output(['cygpath', '-w', jmolpath], 

stderr=subprocess.STDOUT)).rstrip() 

target_native = bytes_to_str(subprocess.check_output(['cygpath', '-w', target_native], 

stderr=subprocess.STDOUT)).rstrip() 

if (datafile_cmd != 'script'): 

datafile = bytes_to_str(subprocess.check_output(['cygpath', '-w', datafile], 

stderr=subprocess.STDOUT)).rstrip() 

launchscript = "" 

if (datafile_cmd!='script'): 

launchscript = "load " 

launchscript = launchscript + datafile 

 

imagescript = 'write {} {!r}\n'.format(image_type, target_native) 

size_arg = "%sx%s" %(figsize*100,figsize*100) 

# Scratch file for Jmol errors 

scratchout = tmp_filename(ext=".txt") 

with open(scratchout, 'w') as jout: 

# Now call the java application and write the file. 

env = dict(os.environ) 

env['LC_ALL'] = 'C' 

env['LANG'] = 'C' 

subprocess.call(["java", "-Xmx512m", "-Djava.awt.headless=true", 

"-jar", jmolpath, "-iox", "-g", size_arg, 

"-J", launchscript, "-j", imagescript], 

stdout=jout, stderr=jout, env=env) 

if not os.path.isfile(targetfile): 

raise RuntimeError("Jmol failed to create file %s, see %s for details"%(repr(targetfile), repr(scratchout))) 

os.unlink(scratchout)