+# 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)
mo_index = 1
mo_ao = nil
coltable = [[0,0,1], [1,0,0], [0,1,0], [1,1,0], [0,1,1], [1,0,1], [0,0,0]]
- if (motype == "RHF")
- beta = nil
+ mo_ao_items = ["Molecular Orbitals", "Atomic Orbitals"]
+ mo_ao_keys = ["MO", "AO"]
+ if (nbo = mol.instance_eval { @nbo }) != nil
+ nbo.keys.each { |key|
+ if key[0..2] == "AO/"
+ key2 = key[3..-1]
+ name2 = key2
+ if key2 == "NAO"
+ name2 = "Natural Atomic Orbitals"
+ elsif key2 == "NBO"
+ name2 = "Natural Bond Orbitals"
+ elsif key2 == "NHO"
+ name2 = "Natural Hybrid Orbitals"
+ elsif key2 == "NLMO"
+ name2 = "Natural Localized Molecular Orbitals"
+ elsif key2 == "PNAO"
+ 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 = "Localized 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
+ }
end
- i = (beta ? 2 : 1)
+ mult = (motype == "UHF" ? 2 : 1)
mo_menu = ["1000 (-00.00000000)"] # Dummy entry; create later
tabvals = []
coeffs = nil
a_idx_old = -1
+ occ = nil
ncomps.times { |i|
- a_idx, label, nprims = mol.get_gaussian_shell_info(i)
+ a_idx, s_idx, label = mol.get_gaussian_component_info(i)
if a_idx_old != a_idx
a_idx_old = a_idx
a = a_idx.to_s
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]
if coeffs == nil
if mo_ao == 0
coeffs = mol.get_mo_coefficients(mo_index)
- else
+ elsif mo_ao == 1
coeffs = (0...ncomps).map { |i| (i == mo_index ? 1.0 : 0.0) }
+ else
+ coeffs = nbo["AO/" + mo_ao_keys[mo_ao]].column(mo_index).to_a[0]
end
end
sprintf("%.6f", coeffs[row])
}
item_with_tag("update")[:enabled] = should_update
end
+ on_update_attr.call
}
on_mo_action = lambda { |it|
mo = it[:value]
if mo_ao == 0
- if beta
+ if motype == "UHF"
mo_index = (mo / 2) + (mo % 2 == 1 ? ncomps : 0) + 1
+ if mo_index <= alpha || (mo_index > ncomps && mo_index <= ncomps + beta)
+ occ_new = 1
+ else
+ occ_new = 0
+ end
else
mo_index = mo + 1
+ if mo_index <= alpha && mo_index <= beta
+ occ_new = 1
+ elsif mo_index <= alpha || mo_index <= beta
+ occ_new = -1
+ else
+ occ_new = 0
+ end
end
else
mo_index = mo
+ occ_new = occ
end
coeffs = nil
+ if occ_new != occ
+ # Set default color
+ col = (occ_new == 0 ? 1 : (occ_new == -1 ? 2 : 0))
+ set_value("color", col)
+ h["color"] = col
+ occ = occ_new
+ 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]
mo_ao = it[:value]
if mo_ao == 0
- mo_menu = (1..(ncomps * i)).map { |n|
- if beta
+ mo_menu = (1..(ncomps * mult)).map { |n|
+ if motype == "UHF"
i1 = (n - 1) / 2 + 1
i2 = n % 2
c1 = (i2 == 0 ? "B" : "A")
i1 = n
i2 = 1
c1 = ""
- c2 = (i1 > alpha ? "*" : "")
+ if i1 > beta && i1 > alpha
+ c2 = "*"
+ elsif i1 > beta || i1 > alpha
+ c2 = "S"
+ else
+ c2 = ""
+ end
end
en = mol.get_mo_energy(i1 + (i2 == 0 ? ncomps : 0))
sprintf("%d%s%s (%.8f)", i1, c1, c2, en)
}
- else
+ elsif mo_ao == 1
mo_menu = []
ncomps.times { |i|
mo_menu[i] = sprintf("AO%d: %s (%s)", i + 1, tabvals[i][2], mol.atoms[tabvals[i][3]].name)
}
+ 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|
+ lab = sprintf("%s%d", key, i + 1)
+ if labels
+ lab += ":" + labels[i]
+ end
+ mo_menu[i] = lab
+ }
end
it0 = item_with_tag("mo")
it0[:subitems] = mo_menu
it0[:value] = 0
+ 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=>"Orbital Set"),
- item(:popup, :tag=>"mo_ao", :subitems=>["Molecular Orbitals", "Atomic Orbitals"], :action=>on_set_action),
+ item(:popup, :tag=>"mo_ao", :subitems=>mo_ao_items, :action=>on_set_action),
item(:text, :title=>"Select"),
item(:popup, :tag=>"mo", :subitems=>mo_menu, :action=>on_mo_action)),
layout(4,
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
show
}
end
+
+ def ask_graphic_export_scale
+ scale = get_global_settings("global.export_graphic_scale")
+ scale = (scale ? scale.to_i - 1 : 3)
+ bg_color = get_global_settings("global.export_background_color")
+ bg_color = (bg_color ? bg_color.to_i + 1 : 0)
+ hash = Dialog.run("Set Export Properties") {
+ layout(2,
+ item(:text, :title=>"Resolution:"),
+ item(:popup, :subitems=>["Screen", "Screenx2", "Screenx3", "Screenx4", "Screenx5"], :tag=>"resolution", :value=>scale),
+ item(:text, :title=>"Background color:"),
+ item(:popup, :subitems=>["Same as Screen", "Transparent", "Black", "White"], :tag=>"bg_color", :value=>bg_color))
+ }
+ if hash[:status] == 0
+ set_global_settings("global.export_graphic_scale", (hash["resolution"] + 1).to_s)
+ set_global_settings("global.export_background_color", (hash["bg_color"] - 1).to_s)
+ return 0
+ else
+ return -1
+ end
+ end
# DEBUG
def cmd_test
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 } )