+# coding: utf-8
#
# commands.rb
#
end
end
+ def cmd_concat_frames
+ n = nframes
+ return if n == 0
+ if Molecule.list.length == 1
+ message_box("No other molecule.", "", :ok)
+ return
+ end
+ ls = (0...Molecule.list.length).select { |i|
+ m = Molecule[i]
+ if m == self || m.natoms != self.natoms
+ false
+ else
+ if nil != (0...m.natoms).find { |n| m.atoms[n].atomic_number != self.atoms[n].atomic_number }
+ false
+ else
+ true
+ end
+ end
+ }
+ if ls.length == 0
+ message_box("No molecule has the same atomic sequence as the present one.", "", :ok)
+ return
+ end
+ labels = []
+ label_hash = Hash.new # Check if documents with the same name are present
+ ls.each_with_index { |i, idx| # i is an index to Molecule, idx is an index to ls
+ m = Molecule[i]
+ label = m.name
+ idx_h = label_hash[label] # If non-nil, then duplicate name
+ label_hash[label] = idx
+ if idx_h
+ if labels[idx_h] == label
+ labels[idx_h] = label + " (" + Molecule[ls[idx_h]].dir + ")"
+ end
+ label = label + " (" + Molecule[i].dir + ")"
+ end
+ labels.push(label)
+ }
+ nf = Molecule[ls[0]].nframes
+ hash = Dialog.run("Concatenate Frames") {
+ layout(2,
+ item(:text, :title=>"From Molecule:"),
+ item(:popup, :subitems=>labels, :tag=>"mol", :width=>240,
+ :action=>lambda { |it|
+ nf = Molecule[ls[it[:value]]].nframes
+ set_attr("start_title", :title=>"Start (0-#{nf})")
+ set_attr("end_title", :title=>"End (0-#{nf})")
+ }),
+ item(:radio, :title=>"All Frames", :tag=>"all_frames", :value=>1,
+ :action=>lambda { |it|
+ flag = (it[:value] == 0)
+ set_attr("start_frame", :enabled=>flag)
+ set_attr("end_frame", :enabled=>flag)
+ }), -1,
+ item(:radio, :title=>"Select Frames", :tag=>"select_frames",
+ :action=>lambda { |it|
+ flag = (it[:value] != 0)
+ set_attr("start_frame", :enabled=>flag)
+ set_attr("end_frame", :enabled=>flag)
+ }), -1,
+ item(:text, :title=>"Start (0-#{nf})", :tag=>"start_title"),
+ item(:textfield, :value=>"0", :tag=>"start_frame", :enabled=>false),
+ item(:text, :title=>"End (0-#{nf})", :tag=>"end_title"),
+ item(:textfield, :value=>"0", :tag=>"end_frame", :enabled=>false))
+ radio_group("all_frames", "select_frames")
+ }
+ if hash[:status] == 0
+ idx_h = Integer(hash["mol"])
+ m = Molecule[ls[idx_h]]
+ f = m.frame # Save the current frame number
+ nf = m.nframes
+ if hash["all_frame"] != 0
+ f1 = 0
+ f2 = nf - 1
+ else
+ f1 = Integer(hash["start_frame"])
+ f2 = Integer(hash["end_frame"])
+ f1 = 0 if f1 < 0
+ f1 = nf - 1 if f1 > nf - 1
+ f2 = 0 if f2 < 0
+ f2 = nf - 1 if f2 > nf - 1
+ end
+ if f1 <= f2
+ a = (f1..f2).to_a
+ else
+ a = (f2..f1).to_a.reverse
+ end
+ prop = m.property_names
+ na = m.natoms
+ a.each { |n|
+ self.create_frame()
+ m.select_frame(n)
+ na.times { |i|
+ self.atoms[i].r = m.atoms[i].r
+ }
+ prop.each { |pr|
+ self.set_property(pr, m.get_property(pr))
+ }
+ }
+ end
+ end
+
def cmd_extra_properties
mol = self
get_count = lambda { |it| mol.nframes }
sprintf("%.8f", mol.get_property(col - 1, row)) rescue ""
end
}
- mol.open_auxiliary_window("Extra Props", nil, nil, :resizable=>true, :has_close_box=>true) {
+ mol.open_auxiliary_window("Extra Props", :resizable=>true, :has_close_box=>true) {
names = nil
@on_document_modified = lambda { |m|
if (n = m.property_names) != names
set_min_size(320, 200)
# listen(mol, "documentModified", on_document_modified)
# listen(mol, "documentWillClose", lambda { |m| close } )
- on_document_modified.call(mol)
+ @on_document_modified.call(mol)
show
}
end
def cmd_show_energy
- wave = [0.0, 0.0]
- cur = 0
- mol = self
- d = open_auxiliary_window("Energy", nil, nil, :resizable=>true, :has_close_box=>true) {
- graph_item = nil # Forward declaration
- target_mol = nil
- draw_graph = lambda { |it|
- clear
- f = graph_item[:frame]
- draw_rectangle(0, 0, f[2], f[3])
- width = f[2] - 25
- height = f[3] - 25
- draw_line(16, 0, 16, height + 12, width + 20, height + 12)
- xx = yy = nil
- min = wave.min
- h = wave.max - min
- h = (h == 0.0 ? 1.0 : height / h)
- w = wave.count
- w = (w == 0 ? 1.0 : Float(width) / w)
- a = []
- wave.each_with_index { |d, i|
- a.push(i * w + 16)
- a.push(height - (d - min) * h + 12)
- }
- if wave.count == 1
- a.push(w + 16)
- a.push(height - (wave[0] - min) * h + 12)
- end
- draw_line(a)
- brush(:color=>[0.2, 0.2, 1.0])
- y = wave[cur] || 0.0
- xx = cur * w + 16
- yy = height - (y - min) * h + 12
- draw_ellipse(cur * w + 16, height - (y - min) * h + 12, 6)
- }
+ wave = [0.0, 0.0]
+ cur = 0
+ mol = self
+ wave_min = lambda { m = 1e8; wave.each { |x| if x != 0.0 && x < m; m = x; end }; m }
+ wave_max = lambda { m = -1e8; wave.each { |x| if x != 0.0 && x > m; m = x; end }; m }
+ d = open_auxiliary_window("Energy", :resizable=>true, :has_close_box=>true) {
+ graph_item = nil # Forward declaration
+ target_mol = nil
+ draw_graph = lambda { |it|
+ clear
+ f = graph_item[:frame]
+ draw_rectangle(0, 0, f[2], f[3])
+ width = f[2] - 25
+ height = f[3] - 25
+ draw_line(16, 0, 16, height + 12, width + 20, height + 12)
+ xx = yy = nil
+ min = wave_min.call
+ max = wave_max.call
+ h = max - min
+ h = (h == 0.0 ? 1.0 : height / h)
+ c = wave.count
+ if c == 0
+ w = 1.0
+ elsif c == 1
+ w = Float(width)
+ else
+ w = Float(width) / (c - 1)
+ end
+ lines = []
+ a = []
+ # Skip the points that have exactly 0.0 value
+ wave.each_with_index { |d, i|
+ if d != 0.0
+ a.push(i * w + 16)
+ a.push(height - (d - min) * h + 12)
+ end
+ if d == 0.0 || i == wave.length - 1
+ # End of this curve fragment
+ if a.length == 0
+ # Do nothing
+ else
+ if a.length == 2
+ if wave.count == 1
+ # If wave has only one point, then draw a horizontal line
+ a.push(a[0] + 16)
+ a.push(a[1])
+ else
+ # Otherwise, draw a zero-length line
+ a.push(a[0])
+ a.push(a[1])
+ end
+ end
+ lines.push(a) # Store this line fragment
+ a = []
+ end
+ end
+ }
+ lines.each { |a|
+ draw_line(a)
+ }
+ brush(:color=>[0.2, 0.2, 1.0])
+ y = wave[cur] || 0.0
+ if y < min
+ y = min
+ elsif y > max
+ y = max
+ end
+ xx = cur * w + 16
+ yy = height - (y - min) * h + 12
+ draw_ellipse(cur * w + 16, height - (y - min) * h + 12, 6)
+ }
@on_document_modified = lambda { |m|
cur = mol.frame
wave.clear
end
def cmd_create_surface
+ if @surface_dialog_attr == nil
+ @surface_dialog_attr = Hash.new
+ @surface_dialog_attr["hidden"] = -1
+ end
+ surface_dialog_attr = @surface_dialog_attr
mol = self
- mol.open_auxiliary_window("MO Surface", nil, nil, :resizable=>true, :has_close_box=>true) {
+ mol.open_auxiliary_window("MO Surface", :resizable=>true, :has_close_box=>true) {
+ tags = ["mo_ao", "mo", "color", "opacity", "threshold", "expand", "grid"]
motype = mol.get_mo_info(:type)
alpha = mol.get_mo_info(:alpha)
beta = mol.get_mo_info(:beta)
name2 = "Pre-orthogonal Natural Atomic Orbitals"
elsif key2 == "PNHO"
name2 = "Pre-orthogonal Natural Hybrid Orbitals"
+ elsif key2 == "PNBO"
+ name2 = "Pre-orthogonal Natural Bond Orbitals"
+ elsif key2 == "AHO"
+ name2 = "Atomic Hybrid Orbitals"
+ elsif key2 == "LHO"
+ name2 = "Lewis Hybrid Orbitals"
+ elsif key2 == "PLHO"
+ name2 = "Pre-orthogonal Lewis Hybrid Orbitals"
+ elsif key2 == "LPO"
+ name2 = "Localized Property-optimized Orbitals"
+ elsif key2 == "CLPO"
+ name2 = "Chemist's Localized Property-optimized Orbitals"
end
mo_ao_items.push(name2)
mo_ao_keys.push(key2)
end
tabvals.push([a, n, label, a_idx])
}
+ on_update_attr = lambda {
+ tags.each { |tag|
+ surface_dialog_attr[tag] = item_with_tag(tag)[:value]
+ }
+ it = item_with_tag("hide")
+ case surface_dialog_attr["hidden"]
+ when -1
+ it[:title] = "Hide"
+ it[:enabled] = false
+ when 0
+ it[:title] = "Hide"
+ it[:enabled] = true
+ when 1
+ it[:title] = "Show"
+ it[:enabled] = true
+ end
+ }
on_get_value = lambda { |it, row, col|
if col < 3
tabvals[row][col]
}
item_with_tag("update")[:enabled] = should_update
end
+ on_update_attr.call
}
on_mo_action = lambda { |it|
mo = it[:value]
end
item_with_tag("table")[:refresh] = true
on_action.call(it)
+ on_update_attr.call
}
on_set_action = lambda { |it|
if mo_ao != it[:value]
else
mo_menu = []
key = mo_ao_keys[mo_ao]
+ labels = nbo[key + "_L"]
+ if labels == nil && key[0] == ?P
+ labels = nbo[key[1..-1] + "_L"]
+ end
ncomps.times { |i|
- mo_menu[i] = sprintf("#{key}%d", i + 1)
+ lab = sprintf("%s%d", key, i + 1)
+ if labels
+ lab += ":" + labels[i]
+ end
+ mo_menu[i] = lab
}
end
it0 = item_with_tag("mo")
h["mo"] = nil # "Update" button is forced to be enabled
on_mo_action.call(it0)
end
+ on_update_attr.call
}
on_update = lambda { |it|
h.each_key { |key|
idx = 0
mol.set_mo_coefficients(0, 0.0, coeffs)
end
- mol.create_surface(idx, :npoints=>grid, :color=>color, :thres=>thres, :expand=>expand, :color0=>color0)
- on_action.call(it)
+ if it[:tag] == "create_cube"
+ basename = File.basename(mol.path || mol.name, ".*")
+ fname1 = Dialog.save_panel("Cube file name", mol.dir || Dir.pwd, basename + ".cube", "Gaussian cube file (*.cube)|*.cube")
+ if fname1
+ mol.cubegen(fname1, idx, grid, true)
+ end
+ else
+ mol.create_surface(idx, :npoints=>grid, :color=>color, :thres=>thres, :expand=>expand, :color0=>color0)
+ mol.show_surface
+ on_action.call(it)
+ surface_dialog_attr["hidden"] = 0
+ on_update_attr.call
+ end
}
layout(1,
layout(2,
item(:text, :title=>"Color"),
item(:popup, :tag=>"color", :subitems=>["blue", "red", "green", "yellow", "cyan", "magenta", "black"], :action=>on_action),
item(:text, :title=>"Opacity"),
- item(:textfield, :tag=>"opacity", :width=>80, :value=>"0.6", :action=>on_action),
+ item(:textfield, :tag=>"opacity", :width=>80, :value=>"0.8", :action=>on_action),
item(:text, :title=>"Threshold"),
item(:textfield, :tag=>"threshold", :width=>80, :value=>"0.05", :action=>on_action),
item(:text, :title=>"Box Limit"),
:on_count=> lambda { |it| tabvals.count },
:on_get_value=>on_get_value,
:flex=>[0,0,0,0,1,1]),
- item(:button, :tag=>"update", :title=>"Update", :action=>on_update, :flex=>[0,1,0,0,0,0]),
+ layout(3,
+ item(:button, :tag=>"update", :title=>"Update", :action=>on_update),
+ item(:button, :tag=>"clear", :title=>"Clear", :action=>lambda { |it|
+ mol.clear_surface
+ item_with_tag("update")[:enabled] = true
+ surface_dialog_attr["hidden"] = -1
+ on_update_attr.call
+ } ),
+ item(:button, :tag=>"hide", :title=>"Hide", :action=>lambda { |it|
+ case surface_dialog_attr["hidden"]
+ when 0
+ surface_dialog_attr["hidden"] = 1
+ mol.hide_surface
+ when 1
+ surface_dialog_attr["hidden"] = 0
+ mol.show_surface
+ end
+ on_update_attr.call
+ } ),
+ item(:button, :tag=>"create_cube", :title=>"Create Cube", :action=>on_update),
+ :flex=>[0,1,0,0,0,0]),
:flex=>[0,0,0,0,1,1]
)
+ tags.each { |tag|
+ if (val = surface_dialog_attr[tag]) != nil
+ item_with_tag(tag)[:value] = val
+ end
+ }
+ mo_idx = surface_dialog_attr["mo"]
+ on_update_attr.call
on_set_action.call(item_with_tag("mo_ao"))
+ item_with_tag("mo")[:value] = surface_dialog_attr["mo"] = mo_idx
size = self.size
set_min_size(size[0], 250)
item_with_tag("table")[:refresh] = true
register_menu("", "")
register_menu("Delete Frames...", :cmd_delete_frames, lambda { |m| m && m.nframes > 1 } )
register_menu("Reverse Frames...", :cmd_reverse_frames, lambda { |m| m && m.nframes > 1 } )
+register_menu("Concatenate Frames...", :cmd_concat_frames, lambda { |m| m && m.nframes > 1 } )
register_menu("", "")
register_menu("Show Energy Window...", :cmd_show_energy, lambda { |m| m && m.property_names.include?("energy") } )
register_menu("Show MO Surface...", :cmd_create_surface, lambda { |m| m && m.get_mo_info(:type) != nil } )