OSDN Git Service

'Show Energy' window is implemented.
authortoshinagata1964 <toshinagata1964@a2be9bc6-48de-4e38-9406-05402d4bc13c>
Wed, 18 Jun 2014 11:06:42 +0000 (11:06 +0000)
committertoshinagata1964 <toshinagata1964@a2be9bc6-48de-4e38-9406-05402d4bc13c>
Wed, 18 Jun 2014 11:06:42 +0000 (11:06 +0000)
git-svn-id: svn+ssh://svn.sourceforge.jp/svnroot/molby/trunk@549 a2be9bc6-48de-4e38-9406-05402d4bc13c

Scripts/commands.rb
Scripts/gamess.rb
Scripts/loadsave.rb
Scripts/md.rb
Scripts/molecule.rb
wxSources/RubyDialogFrame.cpp
wxSources/RubyDialogFrame.h

index 3b7cc7f..8ef7432 100755 (executable)
@@ -154,6 +154,71 @@ class Molecule
        }
   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)
+         }
+         @on_document_modified = lambda { |m|
+               cur = mol.frame
+               wave.clear
+               if mol.nframes < 2
+                 wave = [mol.get_property("energy", 0)] * 2
+               else
+                 wave = (0...mol.nframes).map { |i| mol.get_property("energy", i) }
+               end
+               f = graph_item[:frame]
+               item_with_tag("energy")[:title] = sprintf("Energy = %.10f hartree, Frame = %d", mol.get_property("energy", cur), cur)
+               graph_item.refresh_rect([0, 0, f[2], f[3]])
+         }
+         layout(1,
+               item(:text, :title=>"Energy =                 ", :tag=>"energy"),
+               item(:view, :frame=>[0, 0, 100, 80], :tag=>"graph", :on_paint=>draw_graph, :flex=>[0,0,0,0,1,1]),
+       #       item(:button, :title=>"Update", :action=>doc_modified, :align=>:center, :flex=>[1,1,1,0,0,0]),
+       #       item(:button, :title=>"Close", :action=>proc { hide }, :align=>:center, :flex=>[1,1,1,0,0,0]),
+               :flex=>[0,0,0,0,1,1]
+         )
+         graph_item = item_with_tag("graph")
+         size = self.size
+         set_min_size(size)
+         set_size(500, 300)
+         @on_document_modified.call(mol)
+         show
+       }
+       self
+  end
+  
   #  DEBUG
   def cmd_test
     $test_dialog = Dialog.new("Test") { item(:text, :title=>"test"); show }
@@ -189,6 +254,6 @@ 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("", "")
-register_menu("Open Extra Properties Window...", :cmd_extra_properties, lambda { |m| m && m.property_names.count > 0 } )
+register_menu("Show Energy Window...", :cmd_show_energy, lambda { |m| m && m.property_names.include?("energy") } )
 #register_menu("cmd test", :cmd_test)
 
index 065df14..98bdfa2 100755 (executable)
@@ -403,9 +403,14 @@ class Molecule
     fplog = File.open(logname, "r")
     size = 0
     lines = []
+       lineno = 0
     last_line = ""
     search_mode = 0
-
+       rflag = 0
+       ne_alpha = ne_beta = 0
+       mo_count = 0
+       ncomps = 0
+       
     #  Callback procs
        term_callback = lambda { |m, n|
          msg = "GAMESS execution on #{inpbase} "
@@ -478,6 +483,83 @@ class Molecule
                  elsif line =~ /POINT *([0-9]+) *ON THE REACTION PATH/
                    nserch = $1.to_i
                        last_i = i
+                 elsif line =~ /ATOMIC BASIS SET/
+                       j = i
+                       while j < lines.count
+                         line = lines[j]
+                         break if line =~ /TOTAL NUMBER OF BASIS SET/
+                         j += 1
+                       end
+                       if j < lines.count
+                         #  Found
+                         bs_lines = []
+                         ii = i
+                         while ii <= j
+                           bs_lines.push(lines[ii].chomp)
+                               ii += 1
+                         end
+                         begin
+                           if mol
+                                 ncomps = mol.sub_load_gamess_log_basis_set(bs_lines, lineno + i)
+                               end
+                         rescue
+                           puts $!.to_s
+                           puts $!.backtrace.inspect
+                         end
+                         last_i = j
+                       else
+                         break  #  Wait until all basis set lines are read
+                       end
+                 elsif line =~ /NUMBER OF OCCUPIED ORBITALS/
+                       line =~ /=\s*(\d+)/
+                       n = Integer($1)
+                       if line =~ /ALPHA/
+                         ne_alpha = n
+                       else
+                         ne_beta = n
+                       end
+                 elsif line =~ /SCFTYP=(\w+)/
+                       scftyp = $1
+                       if ne_alpha > 0 || ne_beta > 0
+                         rflag = 0
+                         case scftyp
+                         when "RHF"
+                               rflag = 1
+                         when "ROHF"
+                               rflag = 2
+                         end
+                       end
+                 elsif line =~ /^\s*(EIGENVECTORS|MOLECULAR ORBITALS)\s*$/
+                       if mo_count == 0 && mol
+                         mol.clear_mo_coefficients
+                         mol.set_mo_info(:type=>["UHF", "RHF", "ROHF"][rflag], :alpha=>ne_alpha, :beta=>ne_beta)
+                       end
+                       i += 2
+                       j = i
+                       mo_count += 1
+                       while j < lines.count
+                         line = lines[j]
+                         break if line =~ /\.\.\.\.\.\./ || line =~ /----------------/
+                         j += 1
+                       end
+                       if j == lines.count
+                         break  #  Wait until complete MO info are read
+                       end
+                       ii = i
+                       mo_lines = []
+                       while ii < j
+                         mo_lines.push(lines[ii].chomp)
+                         ii += 1
+                       end
+                       begin
+                         if mol
+                           mol.sub_load_gamess_log_mo_coefficients(mo_lines, lineno + i, ncomps)
+                         end
+                       rescue
+                         puts $!.to_s
+                         puts $!.backtrace.inspect
+                       end
+                       last_i = j
           elsif line =~ /NSERCH: *([0-9]+)/
           #  print line
                        if mol
@@ -528,6 +610,7 @@ class Molecule
           break
         elsif last_i
           lines[0..last_i] = nil
+                 lineno += last_i + 1
         end
       end
       true
@@ -903,7 +986,7 @@ class Molecule
                if bssname
                  user_input["basis"] = $gamess_basis_keys.find_index(bssname).to_s
                end
-           puts user_input.inspect
+         #  puts user_input.inspect
          end
        end
        
@@ -1061,7 +1144,7 @@ class Molecule
          fname = Dialog.save_panel("Export GAMESS input file:", self.dir, basename + ".inp", "GAMESS input file (*.inp)|*.inp|All files|*.*")
          return nil if !fname
          if gamess_input_direct
-           puts "gamess_input_direct = \"#{gamess_input_direct}\""
+         #  puts "gamess_input_direct = \"#{gamess_input_direct}\""
            File.open(fname, "w") { |fp| fp.print(gamess_input_direct) }
          else
            export_gamess(fname, hash)
index 38a7fe0..db3eb00 100755 (executable)
@@ -137,6 +137,7 @@ class Molecule
        nprims = 0
        sym = -10  #  undefined
        ncomps = 0
+       clear_basis_set
        while (line = lines[ln])
                ln += 1
                break if line =~ /TOTAL NUMBER OF BASIS SET/
@@ -186,7 +187,53 @@ class Molecule
        end
        return ncomps
   end
-  
+
+  def sub_load_gamess_log_mo_coefficients(lines, lineno, ncomps)
+    ln = 0
+       idx = 0
+       alpha = true
+       while (line = lines[ln]) != nil
+               ln += 1
+               if line =~ /BETA SET/
+                       alpha = false
+                       next
+               end
+               if line =~ /------------/ || line =~ /EIGENVECTORS/ || line =~ /\*\*\*\* (ALPHA|BETA) SET/
+                       next
+               end
+               next unless line =~ /^\s*\d/
+               mo_labels = line.split       #  MO numbers (1-based)
+               mo_energies = lines[ln].split
+               mo_symmetries = lines[ln + 1].split
+       #       puts "mo #{mo_labels.inspect}"
+               ln += 2
+               mo = mo_labels.map { [] }    #  array of *independent* empty arrays
+               while (line = lines[ln]) != nil
+                       ln += 1
+                       break unless line =~ /^\s*\d/
+                       5.times { |i|
+                         s = line[15 + 11 * i, 11].chomp
+                         break if s =~ /^\s*$/
+                         mo[i].push(Float(s)) rescue print "line = #{line}, s = #{s}"
+                       # line[15..-1].split.each_with_index { |s, i|
+                       #       mo[i].push(Float(s))
+                       }
+               end
+               mo.each_with_index { |m, i|
+                       idx = Integer(mo_labels[i]) - 1
+                       set_mo_coefficients(idx + (alpha ? 0 : ncomps), Float(mo_energies[i]), m)
+               #       if mo_labels[i] % 8 == 1
+               #               puts "set_mo_coefficients #{idx}, #{mo_energies[i]}, [#{m[0]}, ..., #{m[-1]}]"
+               #       end
+               }
+#              if line =~ /^\s*$/
+#                      next
+#              else
+#                      break
+#              end
+       end
+  end
+    
   def sub_load_gamess_log(fp)
 
     if natoms == 0
@@ -333,38 +380,16 @@ class Molecule
                                        set_mo_info(:type=>["UHF", "RHF", "ROHF"][rflag], :alpha=>ne_alpha, :beta=>ne_beta)
                                end
                                mo_count += 1
-                               idx = 0
-                               line = fp.gets; line = fp.gets;
+                               line = fp.gets; line = fp.gets
+                               lineno = fp.lineno
+                               lines = []
                                set_progress_message(mes + "\nReading MO coefficients...")
-                               while (line = fp.gets) != nil
-                                       break unless line =~ /^\s*\d/
-                                       mo_labels = line.split       #  MO numbers (1-based)
-                                       mo_energies = fp.gets.split
-                                       mo_symmetries = fp.gets.split
-                                       mo = mo_labels.map { [] }    #  array of *independent* empty arrays
-                                       while (line = fp.gets) != nil
-                                               break unless line =~ /^\s*\d/
-                                               5.times { |i|
-                                                 s = line[15 + 11 * i, 11].chomp
-                                                 break if s =~ /^\s*$/
-                                                 mo[i].push(Float(s)) rescue print "line = #{line}, s = #{s}"
-                                               # line[15..-1].split.each_with_index { |s, i|
-                                               #       mo[i].push(Float(s))
-                                               }
-                                       end
-                                       mo.each_with_index { |m, i|
-                                               idx = Integer(mo_labels[i]) - 1
-                                               set_mo_coefficients(idx + (alpha_beta == "BETA" ? ncomps : 0), Float(mo_energies[i]), m)
-                                       #       if mo_labels[i] % 8 == 1
-                                       #               puts "set_mo_coefficients #{idx}, #{mo_energies[i]}, [#{m[0]}, ..., #{m[-1]}]"
-                                       #       end
-                                       }
-                                       if line =~ /^\s*$/ && idx < ncomps - 1
-                                               next
-                                       else
-                                               break
-                                       end
+                               while (line = fp.gets)
+                                       break if line =~ /\.\.\.\.\.\./ || line =~ /----------------/
+                                       line.chomp!
+                                       lines.push(line)
                                end
+                               sub_load_gamess_log_mo_coefficients(lines, lineno, ncomps)
                                set_progress_message(mes)
                        end
                end
index b09c4e3..3a8d27d 100755 (executable)
@@ -762,7 +762,7 @@ class Molecule
          end
        }
        message_box(msg, "AMBER Lib Import Complete", :ok)
-       puts msg
+#      puts msg
   end
   
   def Molecule.cmd_import_amberlib(mol)
index e57356c..fab5c8a 100755 (executable)
@@ -725,4 +725,35 @@ class Molecule
        end
   end
   
+  #  Open a Ruby Dialog that is a "child" window of the molecule
+  def open_auxiliary_window(*args, &block)
+    title = args[0] || "(untitled)"
+       mol = self
+       if (win = (@aux_windows ||= Hash.new)[title])
+         win.show
+       else
+         args[0] = self.name + ": " + title
+         d = Dialog.new(*args)
+         if block
+           d.instance_eval(&block)
+               d.instance_eval { |_d|
+             listen(mol, "documentModified", lambda { |m| @on_document_modified.call(m) if @on_document_modified } )
+             listen(mol, "documentWillClose", lambda { |m| m.close_auxiliary_window(_d) } )
+                 @on_close = lambda { mol.close_auxiliary_window(_d, true); true}
+               }
+         end
+         @aux_windows[title] = d
+       end
+       
+  end
+  
+  def close_auxiliary_window(d, is_closing = nil)
+    if @aux_windows && (key = @aux_windows.key(d)) != nil
+         @aux_windows.delete(key)
+       end
+       if !is_closing
+         d.close
+       end
+  end
+  
 end
index 4f93521..0e4d096 100644 (file)
@@ -46,6 +46,8 @@ BEGIN_EVENT_TABLE(RubyDialogFrame, wxDialog)
   EVT_SIZE(RubyDialogFrame::OnSize)
   EVT_CHAR(RubyDialogFrame::OnChar)
   EVT_CLOSE(RubyDialogFrame::OnCloseWindow)
+  EVT_ACTIVATE(RubyDialogFrame::OnActivate)
+  EVT_CHILD_FOCUS(RubyDialogFrame::OnChildFocus)
 END_EVENT_TABLE()
 
 RubyDialogFrame::RubyDialogFrame(wxWindow* parent, wxWindowID wid, const wxString& title, const wxPoint& pos, const wxSize& size, long style):
@@ -61,7 +63,8 @@ RubyDialogFrame::RubyDialogFrame(wxWindow* parent, wxWindowID wid, const wxStrin
        onKeyHandlerEnabled = false;
        currentContext = NULL;
        currentDrawingItem = NULL;
-       
+       lastFocusedWindow = NULL;
+
        //  Create a vertical box sizer that contains a panel containing all controls and a sizer containing
        //  OK/Cancel buttons
        contentSizer = new wxBoxSizer(wxVERTICAL);
@@ -355,6 +358,42 @@ RubyDialogFrame::OnCloseWindow(wxCloseEvent &event)
        wxGetApp().CheckIfAllWindowsAreGone(NULL);
 }
 
+/*  Restore the focused window after reactivation  */
+/*  Only necessary for wxOSX?  */
+void
+RubyDialogFrame::OnActivate(wxActivateEvent &event)
+{
+       if (event.GetActive()) {
+               int i;
+               RDItem *itemp;
+               if (lastFocusedWindow != NULL) {
+                       lastFocusedWindow->SetFocus();
+               } else {
+                       for (i = 0; (itemp = DialogItemAtIndex(i)) != NULL; i++) {
+                               if (((wxWindow *)itemp)->CanAcceptFocus()) {
+                                       ((wxWindow *)itemp)->SetFocus();
+                                       lastFocusedWindow = (wxWindow *)itemp;
+                                       break;
+                               }
+                       }
+               }
+       }
+}
+
+/*  Remember the focused window after every focus change  */
+/*  Only necessary for wxOSX?  */
+void
+RubyDialogFrame::OnChildFocus(wxChildFocusEvent &event)
+{
+       wxWindow *winp = wxWindow::FindFocus();
+       if (winp != NULL) {
+               if (winp != lastFocusedWindow && wxDynamicCast(winp, wxTextCtrl) != NULL && ((wxTextCtrl *)winp)->IsEditable()) {
+                       ((wxTextCtrl *)winp)->SelectAll();
+               }
+               lastFocusedWindow = winp;
+       }
+}
+
 static wxEvtHandler *
 sGetEventHandlerFromObjectAndType(void *obj, wxEventType eventType)
 {
@@ -627,6 +666,7 @@ RubyDialogCallback_show(RubyDialog *dref)
                ((RubyDialogFrame *)dref)->StartIntervalTimer(-1);
        ((RubyDialogFrame *)dref)->Show(true);
        ((RubyDialogFrame *)dref)->Raise();
+       ((RubyDialogFrame *)dref)->Enable();
 #if defined(__WXMAC__)
        {
                extern void AddWindowsItemWithTitle(const char *title);
index eacce00..b4fcc1a 100644 (file)
@@ -60,6 +60,8 @@ public:
        wxWindow *currentDrawingItem;
        wxDC *currentContext;
 
+       wxWindow *lastFocusedWindow;
+
        /*  Auto resizing  */
        RDSize mySize;  /*  Previous size  */
        bool autoResizeEnabled;  /*  true if auto resizing is enabled  */
@@ -97,7 +99,9 @@ public:
        void OnSize(wxSizeEvent &event);
        void OnChar(wxKeyEvent &event);
        void OnCloseWindow(wxCloseEvent &event);
-
+       void OnActivate(wxActivateEvent &event);
+       void OnChildFocus(wxChildFocusEvent &event);
+       
        //  MyListCtrlDataSource methods
        virtual int GetItemCount(MyListCtrl *ctrl);
        virtual wxString GetItemText(MyListCtrl *ctrl, long row, long column) const;