#svl // // exhibition.svl Exhibition Tool // // 05-sep-2014 (yk) bug fix: simultaneous option ignored // 01-aug-2011 (kt) bug fix // 12-jul-2011 (kt) smooth zoom, image file name, etc... // 02-jul-2010 (kt) PNG file // 27-jun-2007 (kt) Start without GUI // 04-apr-2007 (kt) modify tansparency option (use cosine function) // 08-feb-2007 (kt) added ransparency option // 22-jan-2007 (ti) added ViewRotate function // 17-nov-2005 (ti) revised // 20-oct-2005 (ti) Added Output Image option // 28-nov-2003 (kt) Added the shell button / 'Apply', 'Stop' // 30-sep-2003 (kt) create // // COPYRIGHT (C) 2003-2007 RYOKA SYSTEMS INC. ALL RIGHTS RESERVED. // // PERMISSION TO USE, COPY, MODIFY AND DISTRIBUTE THIS SOFTWARE IS HEREBY // GRANTED PROVIDED THAT: (1) UNMODIFIED OR FUNCTIONALLY EQUIVALENT CODE // DERIVED FROM THIS SOFTWARE MUST CONTAIN THIS NOTICE; (2) ALL CODE DERIVED // FROM THIS SOFTWARE MUST ACKNOWLEDGE THE AUTHOR(S) AND INSTITUTION(S); (3) // THE NAMES OF THE AUTHOR(S) AND INSTITUTION(S) NOT BE USED IN ADVERTISING // OR PUBLICITY PERTAINING TO THE DISTRIBUTION OF THE SOFTWARE WITHOUT // SPECIFIC, WRITTEN PRIOR PERMISSION; (4) ALL CODE DERIVED FROM THIS SOFTWARE // BE EXECUTED WITH THE MOLECULAR OPERATING ENVIRONMENT (MOE) LICENSED FROM // RYOKA SYSTEMS INC. // // RYOKA SYSTEMS INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS // SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, // AND IN NO EVENT SHALL RYOKA SYSTEMS INC. BE LIABLE FOR ANY // SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER // RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF // CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. // // // !!!!TODO!!!! // Flexible range for transparency <--- somebody please! (kt) // #set title 'Exhibition' #set class 'RSI:Original' #set main 'Exhibition' function fwrite_BMP; //for MOE2005.06 function fwrite_PNG; //for MOE2005.06 function _Atoms; local function CreateFileName [i, prefix] if isnull prefix then prefix = 'image'; endif local filename = token cat [rep["0",5 - floor log10 i],swrite['{n:}',i]]; filename = tok_cat [prefix, filename, '.png']; return filename; endfunction static status, run_status; static fobj, fobj_fix; static zoom_atom_lock; static saveimage; const RENDERING = ['Cartoon','Line','Tube']; const WINDOW_NAME = 'Exhibition'; const PANEL = [ windowName: WINDOW_NAME, name:'shell', title: 'Exhibition', text: ['OK','Apply','Stop','Close'], onTrigger: ['return','return','return','exit'], Checkbox:[name:'rot', title:'Rotation:',type:'flag', onTrigger:'return'], Hbox:[ Label:[], //Dummy Widget Radio: [ name: 'rot_axis',title: 'Rotation axis: ',onTrigger: 'return', text: ['X','Y','Z'],columns: 3, type: 'tok' ], Text: [ name:'agl',title: 'Step: ',onTrigger: 'return',type: 'real', bubbleHelp: 'By degree',onTrigger:'return' ] ], /* Hbox:[ Label:[], //Dummy Widget Text: [ name:'agl',title: 'Step: ',onTrigger: 'return',type: 'real', bubbleHelp: 'By degree',onTrigger:'return'] //,Text: [ name:'wt',title:' Wait time: ',onTrigger: 'return', //type:'real',bubbleHelp:'By second',onTrigger:'return'] ], */ Separator:[vertical:0,flushLeft:1], Hbox:[ Checkbox:[name:'draw_bb', title:'Backbone:',type:'flag', onTrigger:'return'], Radio:[name:'bb_render',text:['Cartoon','Line','Tube']], Checkbox:[name:'simbb', title:'Simultaneous:',type:'flag', onTrigger:'return'] ], Separator:[vertical:0,flushLeft:1], Hbox:[ Checkbox:[name:'draw_atom', title:'Atoms:',type:'flag', onTrigger:'return'], Radio:[name:'atm_render',text:['Space Filling','Stick','Line']] ], Separator:[vertical:0,flushLeft:1], Hbox:[ Checkbox:[name:'trsp', title:'Transparency:',type:'flag', onTrigger:'return'], Separator:[vertical:1, shadow:'none'], Checkbox:[title:'TF:',name:'tf'], Checkbox:[title:'TB:',name:'tb'], Text:[title:' Speed:',name:'tspeed',type:'real',len:5] ], Separator:[vertical:0,flushLeft:1], Hbox:[ Checkbox:[name:'waver', title:'Slice:',type:'flag', onTrigger:'return'], Text:[name:'z_start',type:'real',len:4,title:'Z-Clip'],Label:[text:' ~ '], Text:[name:'z_end',type:'real',len:4], Text:[title:' Speed:',name:'speed',type:'real',len:5] ], Separator:[vertical:0,flushLeft:1], Hbox:[ Checkbox:[name:'view', title:'Zoom:',type:'flag', onTrigger:'return'], Text:[ name:'viewstep',type:'real',len:4,title:'By', bubbleHelp:'< 100: the number of rotations\n>=100: the number of steps' ], Label:[text:'(Rotation or Steps)',font:'mediumBold'] ], Hbox:[ Button:[name:'fobj', text:'Set Selected Atoms to zoom', onTrigger:'return'], Text:[name:'zoomspeed', title:'Zoom Speed:', type:'int', len:5] ], Separator:[vertical:0,flushLeft:1], Hbox:[ Text:[name:'basesp', title:'Base speed:',type:'int', shortcut:['500','100','50','10','1'],len:6,onTrigger:'return'], Label:[text:'frames / sec.'] ], Hbox:[ Label:[title:'Output image:'], Text:[name:'fprefix', title:'File name prefix:', len:6], Button:[name:'saveimage', text:'Start', onTrigger:'return'], Text:[name:'framenumber', len:4, foreground:'red', background:'background', type:'int',sensitive:0] ] ]; local function AtomLook [nuc_mode, bond_mode,a] if nuc_mode <> '' then aSetNucleusLook [a, nuc_mode] ; endif if bond_mode <> '' then aSetBondLook [a, bond_mode]; endif endfunction // refer to $MOE/lib/svl/run/dials.svl local function ViewRotate [axis, angle] local R = rot3d_Rotation [angle, axis]; local yzdir = ViewOrientation[]; local WCtoVC = [rot3d_vCross yzdir, yzdir(1), yzdir(2)]; local VCtoWC = tr WCtoVC; local vc_center = app add (WCtoVC * [third ViewDataExtent[]]); local vc_lookat = app add (WCtoVC * [ViewLookAt[]]); vc_lookat = vc_center + app add (R * [vc_lookat - vc_center]); ViewLookAt app add (VCtoWC * [vc_lookat]); R = app add (R * [WCtoVC]); R = app add (VCtoWC * [R]); ViewOrientation [app add (R * [yzdir(1)]), app add (R * [yzdir(2)])]; endfunction local function exhib_rotation[] local x, y, z; x = rot3d_vCross ([y,z] = ViewOrientation[]); local axis = ['X','Y','Z'] == status.rot_axis; local angle = (status.agl * PI / 180); angle = angle - (2*PI) * round (angle/(2*PI)); ViewRotate [axis, -angle]; endfunction local function zoom_fit_scale atoms local v = aPos atoms; // get covariance matrix local u = app add v * invz l_length v; local r = sqrt maxE add sqr (v - u); // get radius //r = r + 10; r = r + 20; // ViewLookAt u; // ViewScale maxE[r * 2 / sqrt 2, 6]; return [u, maxE[r * 2 / sqrt 2, 6]]; endfunction function _Atoms; local function exhib_zoom [zoomdir, step, start] if add allfalse oType fobj then fobj = _Atoms '$$ligand'; if isnull fobj then return[]; endif fobj = get [fobj, x_sort aMoleculeNumber fobj]; fobj = split [fobj, btoc aMoleculeNumber fobj]; fobj = first get [fobj, x_sort app length fobj]; endif local zoom_in = zoom_fit_scale fobj; if isnull start then local zoom_out = zoom_fit_scale Atoms[]; else zoom_out = start; endif local lookat = (zoom_in(1) - zoom_out(1)) * inv status.zoomspeed; local scale = (zoom_in(2) - zoom_out(2)) * inv status.zoomspeed; ViewLookAt (zoomdir * lookat + ViewLookAt []); ViewScale (zoomdir * scale + ViewScale []); step = inc step; if step > status.zoomspeed then return [neg zoomdir, 1]; else return [zoomdir, step]; endif endfunction static winkey; local function ExhibitionMovie [] local function define_fobj [] fobj = _Atoms '$$ligand'; if isnull fobj then return[]; endif fobj = get [fobj, x_sort aMoleculeNumber fobj]; fobj = split [fobj, btoc aMoleculeNumber fobj]; fobj = first get [fobj, x_sort app length fobj]; if add allfalse oType fobj then local atoms = Atoms[]; fobj = first shuffle (atoms | not aHidden atoms); endif if add allfalse oType fobj then fobj = first shuffle Atoms[]; endif endfunction if status.rot and status.agl == 0 then Warning 'Exhibiotion\nRotation Step = 0'; run_status = 0; exit[]; endif local r; local i = 0; local j = 0; local k = 0; local m = 0; local trsp = 0; local flag = 1; local simul = 0; local idx = []; local check_r = Residues[]; local frm = 0; local zoomdir = 1; local zoomstp = 1; local zoomlock = 1; loop sleep invz status.basesp; if frm == INT_MAX then frm = 0; endif frm = inc frm; //sleep status.wt; if length check_r > length Residues[] then Warning 'One or more residues have removed.\nExhibitionMovie is stopped.'; run_status = 0; exit[]; endif check_r = Residues[]; local prio = task_prio 0; //////////////////////////Exhibition Loop/////////////////////////////////////// ////////// Ratation ////////// if status.rot then exhib_rotation[]; endif ////////////////////////////// ////////// Zoom ////////// if status.view then if status.viewstep >= 100 then if not mod[frm, status.viewstep] then zoomlock = 0; if not zoom_atom_lock then define_fobj []; endif endif else if not mod[frm, 360 / status.agl * status.viewstep] then zoomlock = 0; if not zoom_atom_lock then define_fobj []; endif endif endif if not zoomlock then if imul [zoomdir, zoomstp] == 1 then local startview = [ViewLookAt[],ViewScale[]]; elseif zoomdir == -1 then startview = []; endif [zoomdir, zoomstp] = exhib_zoom [zoomdir, zoomstp, startview]; if zoomstp == 1 then zoomlock = 1; endif endif endif ////////////////////////////// if status.draw_bb or status.draw_atom then if not (status.simbb === simul) then idx = []; simul = status.simbb; endif i = i + 1; if not mod[i,5] then if not length idx then i = 0; r = Residues[] | (app add indexof[rType Residues[],['amino','dna','l-amino','d-amino','rna']]); if status.simbb then idx = sort uniq rPosSE r; else idx = igen length r; endif if status.draw_bb then rSetRibbonMode[r,'none']; rSetRibbonWidth [r,0]; rSetRibbonHeight [r,0]; endif if status.draw_atom then aSetHidden[cat rAtoms cat r,1]; endif endif if status.simbb then local current_r = r | rPosSE r == first idx; else current_r = r | igen length r == first idx; endif if status.draw_bb and length r then local bb_render = get[['auto','line','tube'],indexof[status.bb_render,RENDERING]]; rSetRibbonWidth[current_r,0]; rSetRibbonHeight[current_r,0]; rSetRibbonMode[current_r,bb_render]; endif if status.draw_atom and length r then if status.atm_render === 'Space Filling' then AtomLook ['sphere','line',cat rAtoms current_r]; elseif status.atm_render === 'Stick' then AtomLook ['point', 'cylinder',cat rAtoms current_r]; elseif status.atm_render === 'Line' then AtomLook ['point','line',cat rAtoms current_r]; endif aSetHidden[cat rAtoms current_r,0]; endif idx = dropfirst idx; endif endif if status.waver then if status.z_start < 0 then status.z_start = 0; endif if status.z_end > 1 then status.z_end = 1; endif if status.z_start < status.z_end then local [start,end]=[status.z_start,status.z_end]; else [start,end]=[status.end,status.start]; endif j = j + status.speed; ViewZFront (start + abs(abs(j-(end - start))-(end - start))); if j >= 2*(end-start) then j = 0; endif elseif j then j = 0; ViewZFront j; endif if status.trsp then status.tspeed = min [status.tspeed, 10]; status.tspeed = max [status.tspeed, 0.1]; local gkey = GKeyList[]; trsp = min [trsp + status.tspeed / 2,255]; local _trsp = ( cos ( trsp / 255 * 2 * PI + PI ) + 1 ) / 2 * 255; // GSetTransparency [GKeyList[], [status.tf, status.tb] * abs( abs ( trsp - 255 ) - 255 )]; GSetTransparency [GKeyList[], round [_trsp, _trsp]*[status.tf, status.tb]]; if trsp >= 255 then trsp = 0; endif elseif trsp then trsp = 0; GSetTransparency [GKeyList[], [trsp,trsp]]; endif // if status.output_bmp then if saveimage then if not (status.draw_bb or status.draw_atom) then i = i+1; endif local file_name = CreateFileName [i, status.fprefix]; // fwrite_BMP [file_name, ViewGetImage[], []]; //for MOE2005.06 fwrite_PNG [file_name, ViewGetImage[], []]; //for MOE2005.06 WindowSetData [winkey, [framenumber:i]]; endif task_prio prio; until run_status === 0 endloop exit[]; endfunction const EXHI_DEFAULT = [ rot:1, rot_axis:'Y', agl:0.3, wt:0.01, draw_bb:0, bb_render:'Cartoon', simbb:1, draw_atom:0, atm_render:'Space Filling', trsp:0, tf:1, tb:1, tspeed:1, waver:0, z_start:0.2, z_end:0.6, speed:0.002, view:0, viewstep:1000, output_bmp:0 ]; global function Exhibition args if not isnull args then status = cat [args,EXHI_DEFAULT]; status = status | m_uniq tags status; run_status = 1; ExhibitionMovie []; endif WindowShow [WINDOW_NAME, 1]; if WindowShow [WINDOW_NAME, 1] then return; endif winkey = WindowCreate PANEL; WindowShow winkey; //display panel WindowSetAttr [ winkey, [ z_start:[sensitive:0],z_end:[sensitive:0],bb_render:[sensitive:0], tf:[sensitive:0],tb:[sensitive:0],tspeed:[sensitive:0], atm_render:[sensitive:0],speed:[sensitive:0],viewstep:[sensitive:0] ] ]; WindowSetData [ winkey, [ rot:1,agl:0.3,z_start:0.2,simbb:1,//wt:0.01, tf:1,tb:1,tspeed:1,z_end:0.6,rot_axis:'Y',speed:0.002,viewstep:1, basesp:100, fprefix:'image', framenumber:0, zoomspeed:100 ] ]; run_status = 0; fobj = []; fobj_fix = 0; zoom_atom_lock = 0; saveimage = 0; loop local [vals, trigger] = WindowWait winkey; if trigger === 'draw_bb' then if vals.draw_bb then WindowSetAttr [winkey, [bb_render:[sensitive:1]]]; else WindowSetAttr [winkey, [bb_render:[sensitive:0]]]; endif elseif trigger === 'draw_atom' then if vals.draw_atom then WindowSetAttr [winkey, [atm_render:[sensitive:1]]]; else WindowSetAttr [winkey, [atm_render:[sensitive:0]]]; endif elseif trigger === 'waver' then if vals.waver then WindowSetAttr [winkey, [z_start:[sensitive:1],z_end:[sensitive:1]]]; WindowSetAttr [winkey, [speed:[sensitive:1]]]; else WindowSetAttr [winkey, [z_start:[sensitive:0],z_end:[sensitive:0]]]; WindowSetAttr [winkey, [speed:[sensitive:0]]]; endif elseif trigger === 'view' then if vals.view then WindowSetAttr [winkey, [viewstep:[sensitive:1]]]; else WindowSetAttr [winkey, [viewstep:[sensitive:0]]]; endif elseif trigger === 'trsp' then if vals.trsp then WindowSetAttr [winkey, [tf:[sensitive:1],tb:[sensitive:1]]]; WindowSetAttr [winkey, [tspeed:[sensitive:1]]]; else WindowSetAttr [winkey, [tf:[sensitive:0],tb:[sensitive:0]]]; WindowSetAttr [winkey, [tspeed:[sensitive:0]]]; endif elseif trigger === 'fobj' then if zoom_atom_lock then fobj = []; zoom_atom_lock = 0; WindowSetAttr[winkey, [fobj:[text:['Set selected atoms to zoom']]]]; else fobj = SelectedAtoms[]; zoom_atom_lock = 1; WindowSetAttr[winkey, [fobj:[text:['Unset zoom atoms']]]]; endif elseif trigger == 'saveimage' then saveimage = not saveimage; WindowSetAttr[winkey, [saveimage:[text:select['Stop','Start',saveimage]]]]; elseif trigger === 'shell' then if vals.shell === 'OK' then WindowShow [winkey,0]; //Hide panel status = vals; if not run_status then run_status = 1; ExhibitionMovie []; endif endif if vals.shell === 'Apply' then status = vals; if not run_status then run_status = 1; if second task_fork[master:'parent'] == 'child' then ExhibitionMovie []; exit[]; endif endif endif if vals.shell === 'Stop' then run_status = 0; endif endif endloop endfunction