;$Id: rmd_cmrotor.pro,v 1.2 2007/03/02 23:31:32 azuah Exp $
; +
; NAME:
;  RMD_CMROTOR
;
; PURPOSE:
;  This calculator allows the user to determine the eigenvalues
;  for two coupled methyl rotors each under the influence of a
;  3-fold barrier, (Vi/2)*(1-cos(3*Oi+Ai)), where Vi is the barrier to
;  reorientation for the ith rotor (i=1,2), Oi is its rotational
;  coordinate, and Ai is the angular offset between the rotors (A1 = 0,
;  A2 is user specified as "ALPHA".  In addition, a coupling term
;  (-W3/2)*(1-cos(3O1-3O2)), is added.
;
; CATEGORY:
;  Chemical dynamics calculations, DAVE software
;
; REQUIRED PROGRAMS:
;  SOURCEPATH
;
; COMMON BLOCKS:
;  None
;
; AUTHOR:
;   Robert M. Dimeo, Ph.D.
;   NIST Center for Neutron Research
;   100 Bureau Drive
;   Gaithersburg, MD 20899
;   Phone: (301) 975-8135
;   E-mail: robert.dimeo@nist.gov
;   http://www.ncnr.nist.gov/staff/dimeo
;
; MODIFICATION HISTORY:
;  Written by RMD 2-25-07
;
; -
; ***************************************** ;
pro rmd_cmrotor_centertlb,tlb
device,get_screen_size = screenSize
; Note that we need to test for whether this application is
; running on a two-monitor (side-by-side) system.
aspect_ratio = float(screenSize[0])/float(screenSize[1])
dual_monitor = 0b;aspect_ratio gt (4./3.)
geom = widget_info(tlb,/geometry)
if dual_monitor then begin
   widget_control,tlb,  xoff = (screenSize[0]/4)-(geom.scr_xsize/2),$
                        yoff = (screenSize[1]/2)-(geom.scr_ysize/2)
endif else begin
   widget_control,tlb,  xoff = (screenSize[0]/2)-(geom.scr_xsize/2),$
                        yoff = (screenSize[1]/2)-(geom.scr_ysize/2)
endelse
end
; ***************************************** ;
function cmr_kronecker,i,j
; Kronecker delta function
; K(i,j) = 1 if i=j, 0 otherwise
compile_opt idl2,hidden
return,double(i eq j)
end
; ***************************************** ;
function rmd_cmh,B,V31,V32,ALPHA,W3,NUM,TIME = TIME
;
; This function constructs the Hamiltonian for two coupled
; methyl rotors based on a basis of free rotor eigenstates.
;
; Required Parameters:
;
;  B:       Free rotor energy level for methyl group (usually 0.655 meV)
;  V31:     Barrier height for rotor #1 (in meV)
;  V32:     Barrier height for rotor #2 (in meV)
;  ALPHA:   Phase angle of rotor #2 w.r.t. rotor #1
;  W:       Coupling constant (in meV)
;  NUM:     Number of terms in the expansion for a *SINGLE* rotor (e.g. 21,31,41,...)
;
compile_opt idl2,hidden
tstart = systime(/seconds)
alpha = alpha*!dtor
hsize = NUM^2
; Create the indices
nlo = -(NUM-1)/2 & nhi = -nlo
mlo = nlo & mhi = -mlo
n = nlo+indgen(NUM)
m = mlo+indgen(NUM)
n_ind = n
m_ind = intarr(hsize)

for i = 1,NUM-1 do n_ind = [n_ind,n]
for i = 0,hsize-1,NUM do m_ind[i:(i+NUM-1)] = replicate(m[i/NUM],NUM)
n_ind = double(n_ind) & m_ind = double(m_ind)

nmat = rebin(n_ind,hsize,hsize,/sample)
mmat = rebin(m_ind,hsize,hsize,/sample)
zero_mat = dblarr(hsize,hsize)
H_FR = B*(nmat^2+mmat^2)*cmr_kronecker(nmat,transpose(nmat))*cmr_kronecker(mmat,transpose(mmat))
V1 = 0.25*V31*cmr_kronecker(mmat,transpose(mmat))*(2.*cmr_kronecker(nmat,transpose(nmat))- $
   cmr_kronecker(nmat-transpose(nmat)-3D,zero_mat)-cmr_kronecker(nmat-transpose(nmat)+3D,zero_mat))

V2_RE = 0.25*V32*cmr_kronecker(nmat,transpose(nmat))*(2.*cmr_kronecker(mmat,transpose(mmat))- $
        cmr_kronecker(mmat-transpose(mmat)+3D,zero_mat)*cos(alpha)-cmr_kronecker(mmat-transpose(mmat)-3D,zero_mat)*cos(alpha))

V2_IM = 0.25*V32*cmr_kronecker(nmat,transpose(nmat))*sin(alpha)*(cmr_kronecker(mmat-transpose(mmat)-3D,zero_mat)- $
   cmr_kronecker(mmat-transpose(mmat)+3D,zero_mat))

term1 = cmr_kronecker(nmat-transpose(nmat),zero_mat)*    $
        cmr_kronecker(mmat-transpose(mmat),zero_mat)
term2 = cmr_kronecker(nmat-transpose(nmat)+3.0,zero_mat)*    $
        cmr_kronecker(mmat-transpose(mmat)-3.0,zero_mat)
term3 = cmr_kronecker(nmat-transpose(nmat)-3.0,zero_mat)*    $
        cmr_kronecker(mmat-transpose(mmat)+3.0,zero_mat)
W = 0.25*W3*(2.*term1-term2-term3)
;W = 0.5*W3*(term2+term3)

H = dcomplex(H_FR+V1+V2_RE-W,V2_IM)
tfinish = systime(/seconds)
TIME = tfinish-tstart
return,H
end
; ***************************************** ;
function rmd_cmrotor_sort_energies,eigenvalues,tol = tol
compile_opt idl2,hidden
if n_elements(tol) eq 0 then tol = 1d-8
; This function groups like energies together.  Also it determines
; the degeneracy of each energy.
nvals = n_elements(eigenvalues)
evals = eigenvalues
eout = evals[0]

for i = 1,nvals-1 do begin
   ; compare the last one to this one
   if (evals[i]-evals[i-1]) ge tol then begin
      eout = [eout,evals[i]]
   endif
endfor
nout = n_elements(eout)
deg = intarr(nout)
for i = 0,nout-1 do begin
   qty = evals - eout[i]
   ok = where(abs(qty) le tol,count)
   deg[i] = count
endfor
return,{eout:eout,degeneracy:deg}
end
; ***************************************** ;
function rmd_cmrotor_initialize
compile_opt idl2,hidden
; This function performs a quick test to characterize the speed
; of the computer on which this program is running.  This information
; will be used when the user wishes to estimate the length of a particular
; calculation.
B = 0.655 & V31 = (V32 = 41.0) & W3 = 5.0 & ALPHA = 0.0
ntimes = 5
tconstruct = fltarr(ntimes)
tdiagonalize = fltarr(ntimes)
time = 0.0
num = 1
while time lt 1.e-6 do begin
   h = rmd_cmh(B,V31,V32,ALPHA,W3,num,TIME = TIME)
   num = num+2
endwhile

num = num+2*indgen(ntimes)
for i = 0,ntimes-1 do begin
   h = rmd_cmh(B,V31,V32,ALPHA,W3,NUM[i],TIME = TIME)
   tconstruct[i] = time
   tstart = systime(/seconds)
   evals = la_eigenql(h,/double)
   evals = real_part(evals)
   tfinish = systime(/seconds)
   tdiagonalize[i] = tfinish - tstart
   print,num[i]
endfor

nlog = alog10(num)
ok_con = where(tconstruct gt 0.0)
ok_diag = where(tdiagonalize gt 0.0)
tconlog = alog10(tconstruct[ok_con])

tdiaglog = alog10(tdiagonalize[ok_diag])
con_result = linfit(nlog[ok_con],tconlog)
diag_result = linfit(nlog[ok_diag],tdiaglog)

ret_val =   {  acon:con_result[0],     $
               bcon:con_result[1],     $
               adiag:diag_result[0],   $
               bdiag:diag_result[1]    }
return,ret_val
end
; ***************************************** ;
pro rmd_cmrotor_estimate_time,event
compile_opt idl2,hidden

; Basic error Handler
if (n_elements(!debug) && (!debug eq 0)) then begin
    catch, catchError
    if (catchError ne 0) then begin
        ;;print, 'Error handled!'
        eTitle = 'RMD_CMROTOR: Error encountered'
        eMsg = 'An error or unusual condition was encountered!'
        eMsg = [eMsg,'Please, report the following to the DAVE team:']
        eMsg = [eMsg,!error_state.msg]
        void = dialog_message(/error,eMsg,title=eTitle,dialog_parent=event.top)
        catch, /cancel
        return
    endif
endif

widget_control,event.top,get_uvalue = pstate
rmd_cmrotor_update_size,event
acon = (*pstate).time_result.acon
bcon = (*pstate).time_result.bcon
adiag = (*pstate).time_result.adiag
bdiag = (*pstate).time_result.bdiag
widget_control,(*pstate).num_id,get_value = val
n = double(val[0])
tconstruct = (10.^acon)*(n^bcon)
tdiag = (10.^adiag)*(n^bdiag)
t = tconstruct + tdiag
f = '(f15.5)'
val = strtrim(string(t,format = f),2)
widget_control,(*pstate).calc_time_id,set_value = val
end
; ***************************************** ;
pro rmd_cmrotor_cleanup,tlb
compile_opt idl2,hidden
widget_control,tlb,get_uvalue = pstate
heap_free,pstate
help,/heap,/brief
end
; ***************************************** ;
function rmd_cmrotor_display_evals,event,evals,deg
compile_opt idl2,hidden

; Basic error Handler
if (n_elements(!debug) && (!debug eq 0)) then begin
    catch, catchError
    if (catchError ne 0) then begin
        ;;print, 'Error handled!'
        eTitle = 'RMD_CMROTOR: Error encountered'
        eMsg = 'An error or unusual condition was encountered!'
        eMsg = [eMsg,'Please, report the following to the DAVE team:']
        eMsg = [eMsg,!error_state.msg]
        void = dialog_message(/error,eMsg,title=eTitle,dialog_parent=event.top)
        catch, /cancel
        return, 0
    endif
endif


widget_control,event.top,get_uvalue = pstate
evals_id = (*pstate).evals_id
if n_params() eq 1 then begin
   evals = *(*pstate).evals_ptr
   deg = *(*pstate).degeneracy_ptr
endif
txt = strtrim(string(evals),2)+' (g='+strtrim(string(deg),2)+')'
widget_control,evals_id,set_value = txt
return,1
end
; ***************************************** ;
function rmd_cmrotor_display_tvals,event
compile_opt idl2,hidden

; Basic error Handler
if (n_elements(!debug) && (!debug eq 0)) then begin
    catch, catchError
    if (catchError ne 0) then begin
        ;;print, 'Error handled!'
        eTitle = 'RMD_CMROTOR: Error encountered'
        eMsg = 'An error or unusual condition was encountered!'
        eMsg = [eMsg,'Please, report the following to the DAVE team:']
        eMsg = [eMsg,!error_state.msg]
        void = dialog_message(/error,eMsg,title=eTitle,dialog_parent=event.top)
        catch, /cancel
        return, 0
    endif
endif


widget_control,event.top,get_uvalue = pstate
tvals_id = (*pstate).tvals_id
tvals = *(*pstate).tvals_ptr
txt = strtrim(string(tvals),2)
widget_control,tvals_id,set_value = txt
return,1
end

; ***************************************** ;
pro rmd_cmrotor_calculate,event
compile_opt idl2,hidden

; Basic error Handler
if (n_elements(!debug) && (!debug eq 0)) then begin
    catch, catchError
    if (catchError ne 0) then begin
        ;;print, 'Error handled!'
        eTitle = 'RMD_CMROTOR: Error encountered'
        eMsg = 'An error or unusual condition was encountered!'
        eMsg = [eMsg,'Please, report the following to the DAVE team:']
        eMsg = [eMsg,!error_state.msg]
        void = dialog_message(/error,eMsg,title=eTitle,dialog_parent=event.top)
        catch, /cancel
        return
    endif
endif


widget_control,event.top,get_uvalue = pstate
widget_control,(*pstate).status_id,set_value = 'Constructing the Hamiltonian...'
widget_control,(*pstate).B_id,get_value = B & B = double(B[0])
widget_control,(*pstate).V31_id,get_value = V31 & V31 = double(V31[0])
widget_control,(*pstate).V32_id,get_value = V32 & V32 = double(V32[0])
widget_control,(*pstate).W3_id,get_value = W3 & W3 = double(W3[0])
widget_control,(*pstate).num_id,get_value = n & n = fix(n[0])
widget_control,(*pstate).phase_id,get_value = alpha & alpha = double(alpha[0])
if ((n+1) mod 2) ne 0 then begin
   msg = 'Number of indices must be an odd number'
   void = dialog_message(dialog_parent = event.top,msg)
   return
endif
rmd_cmrotor_update_size,event
widget_control,(*pstate).base_id,sensitive = 0
; Construct the Hamiltonian
h = rmd_cmh(B,V31,V32,alpha,W3,n,TIME = tconstruct)
widget_control,(*pstate).status_id,set_value = 'Diagonalizing the Hamiltonian...'
; Diagonalize the Hamiltonian
tstart = systime(/seconds)
evals = la_eigenql(h,/double)
evals = real_part(evals)
tfinish = systime(/seconds)
tdiagonalize = tfinish - tstart
print,'Time elapsed: ',tconstruct + tdiagonalize
widget_control,(*pstate).base_id,sensitive = 1
esort = sort(evals)
evals = evals[esort]
result = rmd_cmrotor_sort_energies(evals)
evals = result.eout
*(*pstate).degeneracy_ptr = result.degeneracy
*(*pstate).evals_ptr = evals
nvals = n_elements(evals)
widget_control,(*pstate).ref_state_id,set_slider_max = nvals-2
widget_control,(*pstate).ref_state_id,get_value = val
widget_control,(*pstate).ref_state_id,set_value = 0
tvals = evals[val+1:nvals-1] - evals[val]
*(*pstate).tvals_ptr = tvals
ret = rmd_cmrotor_display_evals(event)
ret = rmd_cmrotor_display_tvals(event)
widget_control,(*pstate).status_id,set_value = 'Idle'
end
; ***************************************** ;
pro rmd_cmrotor_update_size,event
compile_opt idl2,hidden

; Basic error Handler
if (n_elements(!debug) && (!debug eq 0)) then begin
    catch, catchError
    if (catchError ne 0) then begin
        ;;print, 'Error handled!'
        eTitle = 'RMD_CMROTOR: Error encountered'
        eMsg = 'An error or unusual condition was encountered!'
        eMsg = [eMsg,'Please, report the following to the DAVE team:']
        eMsg = [eMsg,!error_state.msg]
        void = dialog_message(/error,eMsg,title=eTitle,dialog_parent=event.top)
        catch, /cancel
        return
    endif
endif

widget_control,event.top,get_uvalue = pstate
widget_control,(*pstate).num_id,get_value = val
val = fix(val[0])
hsize = strtrim(string(val^2),2)
txt = '['+hsize+','+hsize+']'
widget_control,(*pstate).hamiltonian_size_id,set_value = txt
end
; ***************************************** ;
pro rmd_cmrotor_quit,event
compile_opt idl2,hidden
widget_control,event.top,/destroy
end
; ***************************************** ;
function rmd_cmrotor_restore,event
compile_opt idl2,hidden

; Basic error Handler
if (n_elements(!debug) && (!debug eq 0)) then begin
    catch, catchError
    if (catchError ne 0) then begin
        ;;print, 'Error handled!'
        eTitle = 'RMD_CMROTOR: Error encountered'
        eMsg = 'An error or unusual condition was encountered!'
        eMsg = [eMsg,'Please, report the following to the DAVE team:']
        eMsg = [eMsg,!error_state.msg]
        void = dialog_message(/error,eMsg,title=eTitle,dialog_parent=event.top)
        catch, /cancel
        return, 0
    endif
endif

widget_control,event.top,get_uvalue = pstate
dir = (*pstate).dir
save_file = dialog_pickfile(path=(*pstate).dir, /read, $
   title='File to restore',file = filename,filter='*.mrs')
if (save_file eq '') or (~file_test(save_file)) then return,0B
restore,filename = save_file

; Fill in the eigenvalues and the transitions
*(*pstate).evals_ptr = evals
*(*pstate).tvals_ptr = tvals
*(*pstate).degeneracy_ptr = deg
; Fill in all of the widget values
widget_control,(*pstate).num_id,set_value = num
widget_control,(*pstate).B_id,set_value = B
widget_control,(*pstate).V31_id,set_value = V31
widget_control,(*pstate).V32_id,set_value = V32
widget_control,(*pstate).W3_id,set_value = W3
widget_control,(*pstate).phase_id,set_value = alpha
widget_control,(*pstate).ref_state_id,set_slider_min = slider_min_max[0],  $
   set_slider_max = slider_min_max[1],set_value = 0
ret = rmd_cmrotor_display_evals(event,evals,deg)
ret = rmd_cmrotor_display_tvals(event)
return,1B
end
; ***************************************** ;
pro rmd_cmrotor_trans_calc,event
compile_opt idl2,hidden

; Basic error Handler
if (n_elements(!debug) && (!debug eq 0)) then begin
    catch, catchError
    if (catchError ne 0) then begin
        ;;print, 'Error handled!'
        eTitle = 'RMD_CMROTOR: Error encountered'
        eMsg = 'An error or unusual condition was encountered!'
        eMsg = [eMsg,'Please, report the following to the DAVE team:']
        eMsg = [eMsg,!error_state.msg]
        void = dialog_message(/error,eMsg,title=eTitle,dialog_parent=event.top)
        catch, /cancel
        return
    endif
endif

widget_control,event.top,get_uvalue = pstate
widget_control,(*pstate).ref_state_id,get_value = val
if n_elements(*(*pstate).tvals_ptr) eq 0 then return
tvals = *(*pstate).tvals_ptr
widget_control,(*pstate).ref_state_id,get_value = val
nvals = n_elements(*(*pstate).evals_ptr)
evals = *(*pstate).evals_ptr
tvals = evals[val+1:nvals-1] - evals[val]
g = *(*pstate).degeneracy_ptr
deg = g[val:nvals-1]
evals = evals[val:nvals-1]
*(*pstate).tvals_ptr = tvals
ret = rmd_cmrotor_display_tvals(event)
ret = rmd_cmrotor_display_evals(event,evals,deg)
end
; ***************************************** ;
function rmd_cmrotor_save,event
compile_opt idl2,hidden

; Basic error Handler
if (n_elements(!debug) && (!debug eq 0)) then begin
    catch, catchError
    if (catchError ne 0) then begin
        ;;print, 'Error handled!'
        eTitle = 'RMD_CMROTOR: Error encountered'
        eMsg = 'An error or unusual condition was encountered!'
        eMsg = [eMsg,'Please, report the following to the DAVE team:']
        eMsg = [eMsg,!error_state.msg]
        void = dialog_message(/error,eMsg,title=eTitle,dialog_parent=event.top)
        catch, /cancel
        return, 0
    endif
endif

widget_control,event.top,get_uvalue = pstate
; Is there any data to be saved?
if n_elements(*(*pstate).evals_ptr) eq 0 then begin
   txt = 'Must run a calculation first!'
   void = dialog_message(dialog_parent = event.top,txt)
   return,0B
endif
evals = *(*pstate).evals_ptr
tvals = *(*pstate).tvals_ptr
deg = *(*pstate).degeneracy_ptr
; Extract all of the widget values
widget_control,(*pstate).num_id,get_value = num & num = fix(num[0])
widget_control,(*pstate).B_id,get_value = B & B = float(B[0])
widget_control,(*pstate).V31_id,get_value = V31 & V31 = float(V31[0])
widget_control,(*pstate).V32_id,get_value = V32 & V32 = float(V32[0])
widget_control,(*pstate).W3_id,get_value = W3 & W3 = float(W3[0])
widget_control,(*pstate).phase_id,get_value = alpha & alpha = float(alpha[0])
slider_min_max = widget_info((*pstate).ref_state_id,/slider_min_max)
filename = 'cm_rotor_data.mrs'
save_file = dialog_pickfile(path=(*pstate).dir, /write, $
   title='Specify the name of the file to save',file = filename,filter='*.mrs')
if save_file eq '' then return,0B
save,evals,tvals,num,B,V31,V32,alpha,W3,slider_min_max,deg,filename = save_file
return,1B
end
; ***************************************** ;
pro rmd_cmrotor_event,event
compile_opt idl2,hidden
widget_control,event.top,get_uvalue = pstate
uname = widget_info(event.id,/uname)
if uname eq 'UPDATE_SIZE' then rmd_cmrotor_update_size,event
end
; ***************************************** ;
pro rmd_cmrotor_help,event
compile_opt idl2,hidden

; Basic error Handler
if (n_elements(!debug) && (!debug eq 0)) then begin
    catch, catchError
    if (catchError ne 0) then begin
        ;;print, 'Error handled!'
        eTitle = 'RMD_CMROTOR: Error encountered'
        eMsg = 'An error or unusual condition was encountered!'
        eMsg = [eMsg,'Please, report the following to the DAVE team:']
        eMsg = [eMsg,!error_state.msg]
        void = dialog_message(/error,eMsg,title=eTitle,dialog_parent=event.top)
        catch, /cancel
        return
    endif
endif

widget_control,event.top,get_uvalue = pstate

pdf_file = !DAVE_AUXILIARY_DIR+'cmrc_docs.pdf'
void = launch_help(pdf_file,tlb = event.top)
return
end
; ***************************************** ;
pro rmd_cmrotor_about,event
compile_opt idl2,hidden
txt = ['Coupled Methyl Rotor Calculator','written by','Rob Dimeo','February 23, 2007', $
   'NIST Center for Neutron Research']
void = dialog_message(txt,dialog_parent = event.top,/information,/center)
end
; ***************************************** ;
pro rmd_cmrotor,group_leader = group_leader
compile_opt idl2,hidden
device,decomposed = 0 & loadct,0,/silent
if n_elements(group_leader) eq 0 then group_leader = 0L
tlb = widget_base(/col,title = 'Coupled Methyl Rotor Calculator', $
   group_leader = group_leader, /tlb_frame_attr,mbar = bar)
file_menu = widget_button(bar,value = 'File',/menu)
help_menu = widget_button(bar,value = 'Help',/menu)
void = widget_button(file_menu,value = 'Exit',event_pro = 'rmd_cmrotor_quit')
void = widget_button(help_menu,value = 'Help (PDF)', $
   event_pro = 'rmd_cmrotor_help')
void = widget_button(help_menu,value = 'About the Coupled Methyl Rotor program', $
   event_pro = 'rmd_cmrotor_about')
row = widget_base(tlb,/row)
init_value = 'Initialization in progress...'
status_base = widget_base(row,/row,/frame)
void = widget_label(status_base,value = 'Status: ')
status_id = widget_label(status_base,value = init_value,/dynamic_resize)
base_id = widget_base(tlb,/col)
row1 = widget_base(base_id,/row,/align_left)
estimate_calc_button_id = widget_button(row1,value = 'Estimate calculation time = ',$
   event_pro = 'rmd_cmrotor_estimate_time')
calc_time_id = widget_label(row1,value = '0.00',/dynamic_resize)
void = widget_label(row1,value = 'seconds')
row2 = widget_base(base_id,/row,/frame)
num_id = cw_field(row2,title = 'Number of single rotor indices',value = '11',xsize = 3, $
   uname = 'UPDATE_SIZE',/return_events)
void = widget_label(row2,value = '--> Hamiltonian size')
hamiltonian_size_id = widget_label(row2,value = '[121,121]',/dynamic_resize)
row3 = widget_base(base_id,/row,/frame)
col1 = widget_base(row3,/col,/base_align_center)
col1a = widget_base(col1,/col,/base_align_center)
void = widget_label(col1a,value = 'Potential')
void = widget_label(col1a,value = 'parameters')
field_base = widget_base(col1,/col,/base_align_right)
B_id = cw_field(field_base,title = 'B (meV)',value = '0.655',xsize = 5)
V31_id = cw_field(field_base,title = 'V31 (meV)',value = '41.0',xsize = 5)
V32_id = cw_field(field_base,title = 'V32 (meV)',value = '41.0',xsize = 5)
phase_id = cw_field(field_base,title = 'alpha (deg)',value = '30.0',xsize = 5)
W3_id = cw_field(field_base,title = 'W3 (meV)',value = '5.0',xsize = 5)
ref_state_id = widget_slider(field_base,title = 'Reference state',value = 0,  $
   min = 0,max = 2,event_pro = 'rmd_cmrotor_trans_calc')
button_base = widget_base(col1,/col,/base_align_center)
calc_button_id = widget_button(button_base,value = 'Calculate',event_pro = 'rmd_cmrotor_calculate')
save_button_id = widget_button(button_base,value = 'Save results',event_func = 'rmd_cmrotor_save')
restore_button_id = widget_button(button_base,value = 'Restore results',event_func = 'rmd_cmrotor_restore')
quit_id = widget_button(button_base,value = 'Exit',event_pro = 'rmd_cmrotor_quit')
col2 = widget_base(row3,/col)
void = widget_label(col2,value = 'Eigenvalues / meV')
void = widget_label(col2,value = '(degeneracy)')
evals_id = widget_text(col2,xsize = 20,ysize = 20,/scroll)
col3 = widget_base(row3,/col)
void = widget_label(col3,value = 'Transitions to the')
void = widget_label(col3,value = 'reference state / meV')
tvals_id = widget_text(col3,xsize = 20,ysize = 20,/scroll)

rmd_cmrotor_centertlb,tlb
widget_control,tlb,/realize
col_geom = widget_info(col1,/geometry)

widget_control,calc_button_id,xsize = col_geom.xsize
widget_control,save_button_id,xsize = col_geom.xsize
widget_control,restore_button_id,xsize = col_geom.xsize
widget_control,quit_id,xsize = col_geom.xsize

h_ptr = ptr_new(/allocate_heap)
evals_ptr = ptr_new(/allocate_heap)
tvals_ptr = ptr_new(/allocate_heap)
widget_control,base_id,sensitive = 0
time_result = rmd_cmrotor_initialize()
widget_control,base_id,sensitive = 1
widget_control,status_id,set_value = 'Idle'
;dir = sourcepath()
dir = (*!dave_defaults).workDir
degeneracy_ptr = ptr_new(/allocate_heap)

state =  {  estimate_calc_button_id:estimate_calc_button_id,               $
            calc_time_id:calc_time_id,                                     $
            dir:dir,                                                       $
            degeneracy_ptr:degeneracy_ptr,                                 $
            base_id:base_id,                                               $
            phase_id:phase_id,                                             $
            ref_state_id:ref_state_id,                                     $
            hamiltonian_size_id:hamiltonian_size_id,                       $
            time_result:time_result,                                       $
            num_id:num_id,                                                 $
            status_id:status_id,                                           $
            quit_id:quit_id,                                               $
            B_id:B_id, V31_id:V31_id, V32_id:V32_id,W3_id:W3_id,           $
            calc_button_id:calc_button_id,                                 $
            save_button_id:save_button_id,                                 $
            restore_button_id:restore_button_id,                           $
            evals_id:evals_id,                                             $
            tvals_id:tvals_id,                                             $
            evals_ptr:evals_ptr,                                           $
            tvals_ptr:tvals_ptr,                                           $
            h_ptr:h_ptr                                                    }

pstate = ptr_new(state,/no_copy)
widget_control,tlb,set_uvalue = pstate

xmanager,'rmd_cmrotor',tlb,/no_block,cleanup = 'rmd_cmrotor_cleanup',   $
   event_handler = 'rmd_cmrotor_event'

end
