ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/owl/trunk/tools/PyMol.java
Revision: 120
Committed: Mon Apr 30 14:02:56 2007 UTC (17 years, 5 months ago) by stehr
File size: 30212 byte(s)
Log Message:
added overloaded method setDistance for use in CM2Pymol for chains without chain code
Line User Rev File contents
1 filippis 40 package tools;
2    
3     import java.sql.*;
4     import java.io.*;
5     import java.util.*;
6     import java.text.*;
7    
8     /**
9     * Package: tools
10     * Class: PyMol
11     * Author: Ioannis Filippis, filippis@molgen.mpg.de
12     * Date: 20/03/2006
13     *
14     * This class serves as a simple PyMol API. Most methods send PyMol commands
15     * to the PrintWriter taken by the constructor, while others return pymol
16     * selection strings. There is also the possibility to send the atomic
17     * coordinates of a specific model of a macromolecule directly from msdsd
18     * and load them on-the-fly.
19     *
20     * Notes:
21 filippis 44 * - variable: this boolean parameter appears in many methods. The idea is that if
22     * the objectName provided is really a PyMol object or selection, then it must be
23     * quoted. However, it may be just a string variable, so it must be evaluated.In
24     * that case parameter variable should be true.
25 filippis 40 * - This is not a full PyMol API. Existing methods wrap basic pymol commands
26 filippis 48 * in a simple, rather stupid way to facilitate contact graph visualization.
27     * - If you want to use cgo edges, create a .pymolrc file in your home directory
28     * with the command "run /project/StruPPi/PyMolAll/pymol/scripts/ioannis/graph.py"
29 filippis 40 *
30     * Changelog:
31 filippis 45 * 27/03/06 modified by IF (refresh method plus refresh added in saveImage)
32     * 23/03/06 modified by IF (python string methods added plus removeList,concatList methods)
33 filippis 44 * 22/03/06 modified by IF (objectNameQuotes class variable replaced by
34     * method parameter variable)
35 filippis 40 * 20/03/06 first created by IF
36     */
37     public class PyMol {
38    
39     // Out: the PrintWriter where PyMol commands are sent to
40     // attrs: a HashMap with keys the PyMol state variables allowed to be set
41     // by the set class. Values are integers (could be used in a "switch")
42     // DF: used to format decimal numbers so commands issued are readable
43     private PrintWriter Out = null;
44     private HashMap<String, Integer> attrs = new HashMap<String, Integer>();
45     private DecimalFormat DF = new DecimalFormat("#0.000");
46    
47 dinse 118
48    
49 filippis 40 // constructor
50     public PyMol(PrintWriter out) {
51    
52     this.Out = out;
53    
54     attrs.put("sphere_transparency", new Integer(1));
55     attrs.put("sphere_scale", new Integer(2));
56     attrs.put("dash_gap", new Integer(3));
57     attrs.put("dash_width", new Integer(4));
58 filippis 45 attrs.put("transparency", new Integer(5));
59 filippis 40
60     }
61    
62     /**
63     * sends the atom lines of a model (modelId) of a biological unit (assemblyId) of a protein
64     * (accessionCode) directly from msdsd. In this way, the structure is loaded wihout temporary
65     * pdb files. The structure object is named using the pattern accessionCode_assemblyId_modelId.
66     *
67     * Notes:
68     * - A connection file is needed to connect to msdsd
69     * - The chain_pdb_code is used in the chainID field in the atom line, while the chain_code is used
70     * in the segID field (due to its length). Therefore, "segi" and not "chain" must be used in pymol
71     * selections (all methods take care of that based on the boolean parameter msdsd)
72     * - There are two versions of sendAtomLines. One that takes the atomic coordinates from the
73     * partial atom_data tables (needs the table number e.g. 1 for atom_data_1, but is faster),
74     * while the other uses the merged table (really slow - should be avoided)
75     * - In general, the method is slow. The use of temporary files should be preferred. Have a look
76     * at Msdsd2Pdb class.
77     */
78     public void sendAtomLines(String accessionCode, int assemblyId, int modelId, int atomDataTblNum, String connFile) {
79    
80     String query = "SELECT CONCAT("+
81     "RPAD(\"ATOM\", 6, \" \"), "+
82     "LPAD(serial, 5, \" \"), "+
83     "\" \", "+
84     "LPAD(chem_atom_name, 4, \" \"), "+
85     "IF(alt_code IS NULL, \" \", alt_code), "+
86     "code_3_letter, "+
87     "\" \", "+
88     "IF(chain_pdb_code IS NULL, \" \", chain_pdb_code), "+
89     "LPAD(residue_serial, 4, \" \"), "+
90     "IF(residue_pdb_insert_code IS NULL, \" \", residue_pdb_insert_code), "+
91     "REPEAT(\" \", 3), "+
92     "LPAD(x, 8, \" \"), "+
93     "LPAD(y, 8, \" \"), "+
94     "LPAD(z, 8, \" \"), "+
95     "LPAD(occupancy, 6, \" \"), "+
96     "REPEAT(\" \", 6), "+
97     "REPEAT(\" \", 6), "+
98     "RPAD(chain_code, 4, \" \") "+
99     ") AS atom_lines FROM msdsd.atom_data_"+atomDataTblNum+" WHERE "+
100     "(assembly_id = "+assemblyId+") AND "+
101     "(model_id = "+modelId+") AND "+
102     "((alt_code = \"A\") OR (alt_code IS NULL)) AND "+
103     "(pdb_group = \"A\") "+
104     "ORDER BY chain_code, residue_serial, serial;";
105    
106     mySQLConnect SQLC = new mySQLConnect();
107     SQLC.readConnectionFile(connFile);
108     Connection conn = SQLC.openConnection();
109    
110     Statement S;
111     ResultSet R;
112    
113     Out.print("cmd.read_pdbstr(\"\"\"");
114    
115     try {
116     S = conn.createStatement();
117     R = S.executeQuery(query);
118     while (R.next()) {
119     Out.println(R.getString(1)+"\\");
120     }
121     R.close();
122     S.close();
123     } // end try
124     catch (SQLException E) {
125     System.out.println("SQLException: " + E.getMessage());
126     System.out.println("SQLState: " + E.getSQLState());
127     System.out.println("VendorError: " + E.getErrorCode());
128     } // end catch
129    
130     SQLC.closeConnection(conn);
131    
132     Out.println("END\"\"\", \""+accessionCode+"_"+assemblyId+"_"+modelId+"\")");
133    
134     }
135    
136     /**
137     * sends the atom lines of a model (modelId) of a biological unit (assemblyId) of a protein
138     * (accessionCode) directly from msdsd. In this way, the structure is loaded wihout temporary
139     * pdb files. The structure object is named using the pattern accessionCode_assemblyId_modelId.
140     *
141     * Notes:
142     * - A connection file is needed to connect to msdsd
143     * - The chain_pdb_code is used in the chainID field in the atom line, while the chain_code is used
144     * in the segID field (due to its length). Therefore, "segi" and not "chain" must be used in pymol
145     * selections (all methods take care of that based on the boolean parameter msdsd)
146     * - There are two versions of sendAtomLines. One that takes the atomic coordinates from the
147     * partial atom_data tables (needs the table number e.g. 1 for atom_data_1, but is faster),
148     * while the other uses the merged table (really slow - should be avoided)
149     * - In general, the method is slow. The use of temporary files should be preferred. Have a look
150     * at Msdsd2Pdb class.
151     */
152     public void sendAtomLines(String accessionCode, int assemblyId, int modelId, String connFile) {
153    
154     String query = "SELECT CONCAT("+
155     "RPAD(\"ATOM\", 6, \" \"), "+
156     "LPAD(serial, 5, \" \"), "+
157     "\" \", "+
158     "LPAD(chem_atom_name, 4, \" \"), "+
159     "IF(alt_code IS NULL, \" \", alt_code), "+
160     "code_3_letter, "+
161     "\" \", "+
162     "IF(chain_pdb_code IS NULL, \" \", chain_pdb_code), "+
163     "LPAD(residue_serial, 4, \" \"), "+
164     "IF(residue_pdb_insert_code IS NULL, \" \", residue_pdb_insert_code), "+
165     "REPEAT(\" \", 3), "+
166     "LPAD(x, 8, \" \"), "+
167     "LPAD(y, 8, \" \"), "+
168     "LPAD(z, 8, \" \"), "+
169     "LPAD(occupancy, 6, \" \"), "+
170     "REPEAT(\" \", 6), "+
171     "REPEAT(\" \", 6), "+
172     "RPAD(chain_code, 4, \" \") "+
173     ") AS atom_lines FROM msdsd.atom_data WHERE "+
174     "(assembly_id = "+assemblyId+") AND "+
175     "(model_id = "+modelId+") AND "+
176     "((alt_code = \"A\") OR (alt_code IS NULL)) AND "+
177     "(pdb_group = \"A\") "+
178     "ORDER BY chain_code, residue_serial, serial;";
179    
180     mySQLConnect SQLC = new mySQLConnect();
181     SQLC.readConnectionFile(connFile);
182     Connection conn = SQLC.openConnection();
183    
184     Statement S;
185     ResultSet R;
186    
187     Out.print("cmd.read_pdbstr(\"\"\"");
188    
189     try {
190     S = conn.createStatement();
191     R = S.executeQuery(query);
192     while (R.next()) {
193     Out.println(R.getString(1)+"\\");
194     }
195     R.close();
196     S.close();
197     } // end try
198     catch (SQLException E) {
199     System.out.println("SQLException: " + E.getMessage());
200     System.out.println("SQLState: " + E.getSQLState());
201     System.out.println("VendorError: " + E.getErrorCode());
202     } // end catch
203    
204     SQLC.closeConnection(conn);
205    
206     Out.println("END\"\"\", \""+accessionCode+"_"+assemblyId+"_"+modelId+"\")");
207    
208     }
209    
210     /**
211     * loads a pdb file
212     *
213     * Notes:
214     * - There are two versions. One of them loads the pdb file specified by its name and the directory path, while
215     * the other just uses the filename.
216     * - Pdb file is expected to have the extension ".pdb".
217     * - The structure object is named using the accession code (extension ".pdb" is trimmed)
218     */
219     public String loadPDB(String pdbFileName, String pdbDir) {
220    
221     Out.println("cmd.load(\""+pdbDir+"/"+pdbFileName+"\", \""+pdbFileName.substring(0, pdbFileName.length()-4)+"\", 1)");
222    
223     return (pdbFileName.substring(0, pdbFileName.length()-4));
224    
225     }
226    
227     /**
228     * loads a pdb file
229     *
230     * Notes:
231     * - There are two versions. One of them loads the pdb file specified by its name and the directory path, while
232     * the other just uses the filename.
233     * - Pdb file is expected to have the extension ".pdb".
234     * - The structure object is named using the accession code (extension ".pdb" is trimmed)
235     */
236     public String loadPDB(String pdbFileName) {
237    
238     Out.println("cmd.load(\""+pdbFileName+"\", \""+pdbFileName.substring(0, pdbFileName.length()-4)+"\", 1)");
239    
240     return (pdbFileName.substring(0, pdbFileName.length()-4));
241    
242     }
243    
244     /**
245     * adds a node as a sphere centered on the Ca of a residue
246     *
247     * Notes:
248     * - The node object is named n.cid.num (e.g. n.A.15 is the 15th residue-node in chain A)
249     * - The msdsd boolean is used to denote whether msdsd is the source of the structure. In that case,
250     * segi is used instead of chain
251     */
252     public String addNode(String cid, int num, boolean msdsd) {
253    
254     String nodeName = "n."+cid+"."+num;
255     String nodeSel = selectNode(cid, num, msdsd, true);
256    
257 filippis 44 Out.println("cmd.create(\""+nodeName+"\", \""+nodeSel+"\")");
258     Out.println("cmd.show(\"sphere\", \""+nodeName+"\")");
259 filippis 40
260     return nodeName;
261    
262     }
263    
264     /**
265     * adds an edge as a distance object between the Ca's of 2 residues
266     *
267     * Notes:
268     * - The edge object is named e.i_cid.i_num.j_cid.j_num (e.g. e.A.1.B.10 is the edge
269     * between the 1st residue-node in chain A and the 10th residue in chain B)
270     * - The msdsd boolean is used to denote whether msdsd is the source of the structure. In that case,
271     * segi is used instead of chain
272     */
273     public String addEdge(String i_cid, int i_num, String j_cid, int j_num, boolean msdsd) {
274 dinse 118
275    
276 filippis 40
277     String edgeName = "e."+i_cid+"."+i_num+"."+j_cid+"."+j_num;
278     String iNodeSel = selectNode(i_cid, i_num, msdsd, true);
279     String jNodeSel = selectNode(j_cid, j_num, msdsd, true);
280    
281 filippis 44 Out.println("cmd.distance(\""+edgeName+"\", \""+iNodeSel+"\", \""+jNodeSel+"\")");
282 filippis 40 Out.println("cmd.hide(\"labels\")");
283    
284     return edgeName;
285    
286     }
287    
288 stehr 120 /** Creates an edge between the C-alpha atoms of the given residues in the given chain.
289     * The selection in pymol will be names pdbFileName+"Sel"+selNum
290     */
291     public void setDistance(int resi1, int resi2, String pdbFilename, int selNum, String chain_pdb_code){
292 dinse 119 Out.println("distance "+ pdbFilename+"Sel"+selNum+" , chain "+chain_pdb_code+" and resi " + resi1 + " and name ca, chain "+chain_pdb_code+" and resi " + resi2 + " and name ca;");
293 dinse 118 }
294    
295 stehr 120 /** Creates an edge between the C-alpha atoms of the given residues.
296     * Use this variant if there is only one unnamed chain in the current structure.
297     * The selection in pymol will be names pdbFileName+"Sel"+selNum
298     */
299     public void setDistance(int resi1, int resi2, String pdbFilename, int selNum){
300     Out.println("distance "+ pdbFilename+"Sel"+selNum+" , resi " + resi1 + " and name ca, resi " + resi2 + " and name ca;");
301     }
302    
303 filippis 40 /**
304     * adds an edge as a sausage Compiled Graphic Object (cgo) between the Ca's of 2 residues
305     *
306     * Notes:
307     * - The edge object is named e.i_cid.i_num.j_cid.j_num (e.g. e.A.1.B.10 is the edge
308     * between the 1st residue-node in chain A and the 10th residue in chain B)
309     * - If the graph is directed, then only half of the user-formatted sausage will be
310     * drawn towards the target node and the rest will be drawn as a thin sausage.
311     * - rgb(color) and half_rgb(half_color) define the color of the two parts of the edge (if directed).
312     * There are two versions of addCgoEdge, one with string (color) and one with array of doubles
313     * (rgb) parameters.
314     * - The msdsd boolean is used to denote whether msdsd is the source of the structure. In that case,
315     * segi is used instead of chain.
316     */
317     public String addCgoEdge(String i_cid, int i_num, String j_cid, int j_num, double[] rgb, double dashGap, double dashLength, double dashRadius, boolean directed, double[] half_rgb, boolean msdsd) {
318    
319     String edgeName = "e."+i_cid+"."+i_num+"."+j_cid+"."+j_num;
320     String iNodeSel = selectNode(i_cid, i_num, msdsd, true);
321     String jNodeSel = selectNode(j_cid, j_num, msdsd, true);
322    
323 filippis 46 Out.println("edge name="+edgeName+", i_node="+iNodeSel+", j_node="+jNodeSel+", r="+DF.format(rgb[0])+", g="+DF.format(rgb[1])+", b="+DF.format(rgb[2])+", dg="+DF.format(dashGap)+", dl="+DF.format(dashLength)+", dr="+DF.format(dashRadius)+", dir="+(directed?1:0)+", dir_r="+DF.format(half_rgb[0])+", dir_g="+DF.format(half_rgb[1])+", dir_b="+DF.format(half_rgb[2])+"");
324 filippis 40
325     return edgeName;
326    
327     }
328    
329     /**
330     * adds an edge as a sausage Compiled Graphic Object (cgo) between the Ca's of 2 residues
331     *
332     * Notes:
333     * - The edge object is named e.i_cid.i_num.j_cid.j_num (e.g. e.A.1.B.10 is the edge
334     * between the 1st residue-node in chain A and the 10th residue in chain B)
335     * - If the graph is directed, then only half of the user-formatted sausage will be
336     * drawn towards the target node and the rest will be drawn as a thin sausage.
337     * - rgb(color) and half_rgb(half_color) define the color of the two parts of the edge (if directed).
338     * There are two versions of addCgoEdge, one with string (color) and one with array of doubles
339     * (rgb) parameters.
340     * - The msdsd boolean is used to denote whether msdsd is the source of the structure. In that case,
341     * segi is used instead of chain.
342     * - Have a look at the /project/StruPPi/PyMolAll/pymol/scripts/ioannis/graph.py with the
343     * implementation of the edge command
344     */
345     public String addCgoEdge(String i_cid, int i_num, String j_cid, int j_num, String color, double dashGap, double dashLength, double dashRadius, boolean directed, String half_color, boolean msdsd) {
346    
347     String edgeName = "e."+i_cid+"."+i_num+"."+j_cid+"."+j_num;
348     String iNodeSel = selectNode(i_cid, i_num, msdsd, true);
349     String jNodeSel = selectNode(j_cid, j_num, msdsd, true);
350    
351 filippis 46 Out.println("edge name="+edgeName+", i_node="+iNodeSel+", j_node="+jNodeSel+", color="+color+", dg="+DF.format(dashGap)+", dl="+DF.format(dashLength)+", dr="+DF.format(dashRadius)+", dir="+(directed?1:0)+", dir_color="+color+"");
352 filippis 40
353     return edgeName;
354    
355     }
356    
357     /**
358     * deletes an object or selection
359     */
360 filippis 44 public void delete(String objectName, boolean variable) {
361 filippis 40
362 filippis 44 Out.println("cmd.delete("+((!variable)?"\""+objectName+"\"":objectName)+")");
363 filippis 40
364     }
365    
366     /**
367     * deletes a node
368     */
369     public void delNode(String cid, int num) {
370    
371     String nodeName = "\"n."+cid+"."+num+"\"";
372     Out.println("cmd.delete("+nodeName+")");
373    
374     }
375    
376     /**
377     * deletes an edge
378     */
379     public void delEdge(String i_cid, int i_num, String j_cid, int j_num) {
380    
381     String edgeName = "\"e."+i_cid+"."+i_num+"."+j_cid+"."+j_num+"\"";
382     Out.println("cmd.delete("+edgeName+")");
383    
384     }
385    
386 dinse 118
387 filippis 40 /**
388 dinse 118 * turns on atom/bond representation for all bonds for an object or selection
389     */
390     public void myShow(String objectName) {
391    
392     Out.println("cmd.show('"+objectName+"')");
393    
394     }
395    
396    
397    
398     /**
399 filippis 40 * turns on atom/bond representation specified by what for an object or selection
400     */
401 filippis 44 public void showWhat(String what, String objectName, boolean variable) {
402 filippis 40
403 filippis 44 Out.println("cmd.show(\""+what+"\", "+((!variable)?"\""+objectName+"\"":objectName)+")");
404 filippis 40
405     }
406    
407     /**
408     * turns on atom/bond representation for all bonds for an object or selection
409     */
410 filippis 44 public void show(String objectName, boolean variable) {
411 filippis 40
412 filippis 44 Out.println("cmd.show(\"everything\", "+((!variable)?"\""+objectName+"\"":objectName)+")");
413 filippis 40
414     }
415    
416    
417     /**
418     * turns on node representation
419     */
420     public void showNode(String cid, int num) {
421    
422     String nodeName = "n."+cid+"."+num;
423     Out.println("cmd.show(\"sphere\", \""+nodeName+"\")");
424    
425     }
426    
427     /**
428     * turns on edge representation
429     */
430     public void showEdge(String i_cid, int i_num, String j_cid, int j_num) {
431    
432     String edgeName = "e."+i_cid+"."+i_num+"."+j_cid+"."+j_num;
433     Out.println("cmd.show(\"everything\", \""+edgeName+"\"");
434    
435     }
436    
437     /**
438     * turns off atom/bond representation specified by what for an object or selection
439     */
440 filippis 44 public void hideWhat(String what, String objectName, boolean variable) {
441 filippis 40
442 filippis 44 Out.println("cmd.hide(\""+what+"\", "+((!variable)?"\""+objectName+"\"":objectName)+")");
443 filippis 40
444     }
445    
446     /**
447     * turns off atom/bond representation for all bonds for an object or selection
448     */
449 filippis 44 public void hide(String objectName, boolean variable) {
450 filippis 40
451 filippis 44 Out.println("cmd.hide(\"everything\", "+((!variable)?"\""+objectName+"\"":objectName)+")");
452 filippis 40
453     }
454    
455 dinse 118
456 filippis 40 /**
457 dinse 118 * turns off atom/bond representation for all bonds for an object or selection
458     */
459     public void myHide(String objectName) {
460    
461     Out.println("cmd.hide('"+objectName+"')");
462    
463     }
464    
465    
466     /**
467 filippis 40 * turns off node representation
468     */
469     public void hideNode(String cid, int num) {
470    
471     String nodeName = "n."+cid+"."+num;
472     Out.println("cmd.hide(\"everything\", \""+nodeName+"\")");
473    
474     }
475    
476     /**
477     * turns off edge representation
478     */
479     public void hideEdge(String i_cid, int i_num, String j_cid, int j_num) {
480    
481     String edgeName = "e."+i_cid+"."+i_num+"."+j_cid+"."+j_num;
482     Out.println("cmd.hide(\"everything\", \""+edgeName+"\")");
483    
484     }
485    
486     /**
487     * creates a named neighbourhood selection using all atoms within distCutOff Angstrom from
488     * all atoms of the specified residue
489     *
490     * Notes:
491     * - The neighbourhood selection is named n.cid.num.N (e.g. n.A.1.N is the neighbourhood of
492     * the 1st residue-node in chain A)
493     * - The msdsd boolean is used to denote whether msdsd is the source of the structure. In that case,
494     * segi is used instead of chain.
495     */
496     public void selNbrPml(String cid, int num, double distCutOff, boolean msdsd) {
497    
498     String nodeNbrName = "n."+cid+"."+num+".N";
499     String nodeSel = selectNode(cid, num, msdsd, false);
500    
501     Out.println("cmd.select(\""+nodeNbrName+"\", \""+nodeSel + " around "+DF.format(distCutOff)+"\")");
502    
503     }
504    
505     /**
506 filippis 45 * creates a selection called name using the atom selection "encoded" in the objectName
507 filippis 40 *
508     * Notes:
509     * - If pink is false, the selection display is disabled (pink stuff go away!!!!)
510     */
511 filippis 45 public void selPml(String name, String objectName, boolean pink, boolean variable) {
512 filippis 40
513 filippis 45 Out.println("cmd.select(\""+name+"\", "+((!variable)?"\""+objectName+"\"":objectName)+")");
514 filippis 40 if (!pink) { Out.println("cmd.disable(\""+name+"\")"); };
515    
516     }
517    
518     /**
519     * returns an atom selection string for a node
520     *
521     * Notes:
522     * - The CA boolean is used to denote whether the Ca atom should be only selected
523     * - The msdsd boolean is used to denote whether msdsd is the source of the structure. In that case,
524     * segi is used instead of chain.
525     */
526     public String selectNode(String cid, int num, boolean msdsd, boolean CA) {
527    
528     return "("+(msdsd?"segi ":"chain ")+(cid.equals("")?"\"\"":cid)+" and resi "+num+(CA?" and name CA":"")+")";
529    
530     }
531    
532     /**
533     * returns an atom selection string for a chain
534     *
535     * Notes:
536     * - The msdsd boolean is used to denote whether msdsd is the source of the structure. In that case,
537     * segi is used instead of chain.
538     */
539     public String selectChain(String cid, boolean msdsd) {
540    
541     return "("+(msdsd?"segi ":"chain ")+(cid.equals("")?"\"\"":cid)+")";
542    
543     }
544    
545 dinse 118 public void select(String name , String residue_nr){
546    
547     Out.println("select "+ name+", resi " + residue_nr );
548     }
549    
550    
551    
552     public int set(String objectName, double value, String object) {
553     if (object == ""){
554    
555     Out.println("set "+objectName+", " + value);}
556    
557     else {
558     Out.println("set "+objectName+", " + value + " in object " + object);
559     }
560     //Out.println("cmd.set(\""+attribute+"\", "+DF.format(value)+", "+((!variable)?"\""+objectName+"\"":objectName)+")");
561    
562     return 0;
563    
564     }
565    
566    
567    
568    
569 filippis 40 /**
570     * changes one of the PyMol state variable (attribute) for a specific object or selection
571     * and sets it equal to the provided value.
572     *
573     * Notes:
574     * - If the state variable is not defined in the attrs hashMap, then set returns -1 else 0.
575     */
576 filippis 44 public int set(String attribute, double value, String objectName, boolean variable) {
577 filippis 40
578     Integer key = null;
579     key = attrs.get(attribute);
580    
581     if (key == null) { return -1; }
582    
583 filippis 44 Out.println("cmd.set(\""+attribute+"\", "+DF.format(value)+", "+((!variable)?"\""+objectName+"\"":objectName)+")");
584 filippis 40
585     return 0;
586    
587     }
588    
589     /**
590     * sets the color for a node
591     */
592 filippis 44 public void setNodeColor(String color, String nodeName, boolean variable) {
593 filippis 40
594 filippis 44 Out.println("cmd.set(\"sphere_color\", \""+color+"\", "+((!variable)?"\""+nodeName+"\"":nodeName)+")");
595 filippis 40
596     }
597    
598     /**
599     * sets the color for an object or selection
600     */
601 filippis 44 public void setColor(String color, String objectName, boolean variable) {
602 filippis 40
603 filippis 44 Out.println("cmd.color(\""+color+"\", "+((!variable)?"\""+objectName+"\"":objectName)+")");
604 filippis 40
605     }
606    
607     /**
608     * define a new color or rather color name based on an existing color
609     */
610     public void createColor(String colorName, String color) {
611    
612     Out.println("cmd.set_color(\""+colorName+"\", cmd.get_color_tuple(cmd.get_color_index(\""+color+"\")))");
613    
614     }
615    
616     /**
617     * define a new color providing the RGB array of doubles
618     */
619     public void createColor(String colorName, double[] rgb) {
620    
621     Out.println("cmd.set_color(\""+colorName+"\", ["+DF.format(rgb[0])+", "+DF.format(rgb[1])+", "+DF.format(rgb[2])+"])");
622    
623     }
624    
625     /**
626 filippis 45 * create/set a string
627 filippis 44 */
628 filippis 45 public void initString(String stringName, String value) {
629 filippis 44
630 filippis 45 Out.println(stringName+" = \""+value+"\"");
631 filippis 44
632     }
633    
634     /**
635 filippis 45 * append to String
636     */
637     public void appendString(String stringName, String value) {
638    
639     Out.println(stringName+" += \""+value+"\"");
640    
641     }
642    
643     /**
644     * rstring a String
645     */
646     public void rstripString(String stringName, String value) {
647    
648     Out.println("string.rstrip("+stringName+", \""+value+"\")");
649    
650     }
651    
652     /**
653     * replace a specific substring within a string with another one
654     */
655     public void replaceString(String stringName, String oldValue, String newValue) {
656    
657     Out.println("string.replace("+stringName+", \""+oldValue+"\", \""+newValue+"\")");
658    
659     }
660    
661     /**
662 filippis 40 * create/initialize a list
663     */
664     public void initList(String listName) {
665    
666     Out.println(listName+" = []");
667    
668     }
669    
670     /**
671     * append objects to a list
672     */
673     public void appendList(String listName, String value) {
674    
675     Out.println(listName+".append(\""+value+"\")");
676    
677     }
678    
679     /**
680 filippis 45 * remove object from a list
681     */
682     public void removeList(String listName, String value) {
683    
684     Out.println(listName+".remove(\""+value+"\")");
685    
686     }
687    
688     /**
689     * concatenate all members of a list of strings into a string using specific seperator
690     */
691     public void concatList(String listName, String sep, String stringName) {
692    
693     Out.println(stringName+" = \""+sep+"\".join("+listName+")");
694    
695     }
696    
697     /**
698 filippis 40 * iterate through list objects
699     *
700     * Notes:
701     * - item is the name of the variable containing the object
702     * - This is the only method that "print" instead of "println".
703     * In this way, a method can be executed at each iteration e.g.
704     * PyMol pml = new PyMol(out);
705     * ...
706     * pml.iterateList("edges", "edge");
707 filippis 44 * pml.setColor("red", edge, true);
708 filippis 40 * - In the previous example, the "edge" parameter in the setColor command
709     * is the name of tha variable holding the actual object. Therefore, it must
710 filippis 44 * be evaluated and so not quoted. This is why setColor is called with true
711     * value for the argument variable
712 filippis 40 */
713     public void iterateList(String listName, String item) {
714    
715     Out.print("for "+item+" in "+listName+":");
716    
717     }
718    
719     /**
720     * opens a log file
721     *
722     * Notes:
723 filippis 45 * - Be careful. All log files are saved with extension .pml. Remember to include it in the fileName!!!!!
724 filippis 40 * - There are two versions. One of them opens the log file specified by its name and the directory path, while
725     * the other just uses the filename.
726     */
727     public void openLog(String fileName, String dir) {
728    
729     Out.println("log_open "+dir+"/"+fileName+".pml");
730    
731     }
732    
733     /**
734     * opens a log file
735     *
736     * Notes:
737 filippis 45 * - Be careful. All log files are saved with extension .pml. Remember to include it in the fileName!!!!!
738 filippis 40 * - There are two versions. One of them opens the log file specified by its name and the directory path, while
739     * the other just uses the filename.
740     */
741     public void openLog(String fileName) {
742    
743     Out.println("log_open "+fileName+".pml");
744    
745     }
746    
747     /**
748     * closes the last opened log file
749     */
750     public void closeLog() {
751    
752     Out.println("log_close");
753    
754     }
755    
756     /**
757 filippis 45 * get the current view into a string
758     */
759     public void getView(String viewName) {
760    
761     Out.println(viewName+" = cmd.get_view()");
762    
763     }
764    
765     /**
766     * get the current view into a string from a log file
767     */
768     public void getFileView(String viewName, String fileName) {
769    
770     String viewStr = "";
771     String line = "", viewLine = "";
772     boolean viewFinished = false;
773    
774     try {
775     //read the first view in the file
776     BufferedReader fileIn = new BufferedReader(new FileReader(new File(fileName)));
777     while ( ((line = fileIn.readLine()) != null) && (!viewFinished) ){
778     if (line.equals("_ set_view (\\")) {
779     while ( ((viewLine = fileIn.readLine()) != null) && (!viewFinished) ) {
780     if (viewLine.startsWith("_")) {
781     viewStr = viewStr + viewLine.substring(1,viewLine.length()-1);
782     } else {
783     viewFinished = true;
784     }
785     }
786     }
787     }
788     if (fileIn != null) { fileIn.close(); }
789     viewStr = "("+viewStr+")";
790     }
791     catch (Exception e) { System.out.println(e); }
792     Out.println(viewName+" = "+viewStr);
793    
794     }
795    
796     /**
797     * set the view based on a string's value
798     */
799     public void setView(String view) {
800    
801     Out.println("cmd.set_view("+view+")");
802    
803     }
804    
805     /**
806 filippis 40 * writes a png format image file of the current frame
807     *
808     * Notes:
809     * - rayTraced defines whether the image will be ray-traced or not
810     * - There are two versions. One of them saves the image file as specified by its name and the directory path,
811     * while the other just uses the filename.
812     */
813     public void saveImage(String imageName, String dir, boolean rayTraced) {
814    
815 filippis 46 refresh();
816 filippis 40 if (rayTraced) { Out.println("ray"); }
817     Out.println("png "+dir+"/"+imageName+".png");
818    
819     }
820    
821     /**
822     * writes a png format image file of the current frame
823     *
824     * Notes:
825     * - rayTraced defines whether the image will be ray-traced or not
826     * - There are two versions. One of them saves the image file as specified by its name and the directory path,
827     * while the other just uses the filename.
828     */
829     public void saveImage(String imageName, boolean rayTraced) {
830    
831 filippis 45 refresh();
832 filippis 40 if (rayTraced) { Out.println("ray"); }
833     Out.println("png "+imageName+".png");
834    
835     }
836    
837     /**
838     * sources a pymol command script
839     *
840     * Notes:
841     * - There are two versions. One of them runs the file specified by its name and the directory path,
842     * while the other just uses the filename.
843     */
844     public void runScript(String fileName, String dir) {
845    
846     Out.println("@"+dir+"/"+fileName+".pml");
847    
848     }
849    
850     /**
851     * sources a pymol command script
852     *
853     * Notes:
854     * - There are two versions. One of them runs the file specified by its name and the directory path,
855     * while the other just uses the filename.
856     */
857     public void runScript(String fileName) {
858    
859     Out.println("@"+fileName+".pml");
860    
861     }
862    
863     /**
864     * zooms on an object or selection
865     */
866 filippis 44 public void zoom(String objectName, boolean variable) {
867 filippis 40
868 filippis 44 Out.println("cmd.zoom("+((!variable)?"\""+objectName+"\"":objectName)+")");
869 filippis 40
870     }
871    
872     /**
873     * sets the background color
874     */
875     public void background(String color) {
876    
877     Out.println("cmd.bg_color(\""+color+"\")");
878    
879     }
880    
881     /**
882 filippis 45 * refresh the scene
883     */
884     public void refresh() {
885    
886     Out.println("cmd.refresh()");
887    
888     }
889    
890     /**
891 filippis 40 * some initialization commands for structure visualization
892     *
893     * Notes:
894     * - These are defined according to Ioannis' preferences
895     */
896     public void init() {
897    
898     Out.println("cmd.set(\"depth_cue\", 0)");
899     Out.println("cmd.set(\"ray_trace_fog\", 0)");
900     Out.println("cmd.hide()");
901     Out.println("cmd.show(\"cartoon\")");
902     Out.println("cmd.cartoon(\"automatic\")");
903     Out.println("cmd.set(\"cartoon_flat_sheets\", 0)");
904     Out.println("cmd.set(\"cartoon_fancy_helices\", 1)");
905     Out.println("cmd.hide(\"spheres\", \"hetatm\")");
906    
907     }
908    
909     }