aims_project_windows 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +5 -0
- data/bin/AimsCalc +367 -0
- data/bin/AimsProject +88 -0
- data/bin/AimsProjectManager +39 -0
- data/lib/aims_project/aims_project_exception.rb +42 -0
- data/lib/aims_project/aims_project_geometry.rb +52 -0
- data/lib/aims_project/app_controller.rb +245 -0
- data/lib/aims_project/atom.rb +95 -0
- data/lib/aims_project/calculation.rb +406 -0
- data/lib/aims_project/calculation_tree.rb +65 -0
- data/lib/aims_project/calculation_window.rb +141 -0
- data/lib/aims_project/crystal_viewer.rb +994 -0
- data/lib/aims_project/crystal_viewer_options.rb +103 -0
- data/lib/aims_project/geometry_console.rb +155 -0
- data/lib/aims_project/geometry_editor.rb +83 -0
- data/lib/aims_project/geometry_file.rb +183 -0
- data/lib/aims_project/geometry_window.rb +160 -0
- data/lib/aims_project/green_arrow.jpg +0 -0
- data/lib/aims_project/inspector.rb +183 -0
- data/lib/aims_project/material.rb +30 -0
- data/lib/aims_project/octree.rb +5 -0
- data/lib/aims_project/pan.gif +0 -0
- data/lib/aims_project/project.rb +102 -0
- data/lib/aims_project/project_tree.rb +62 -0
- data/lib/aims_project/rotate.gif +0 -0
- data/lib/aims_project/thread_callback_event.rb +19 -0
- data/lib/aims_project/zoom.gif +0 -0
- data/lib/aims_project.rb +158 -0
- data/skeleton/Capfile +37 -0
- data/skeleton/config/aims.sh +58 -0
- data/skeleton/config/tasks.rb +145 -0
- data/skeleton/config/user_variables.rb +37 -0
- data/skeleton/control/example.erb +41 -0
- data/skeleton/geometry/example +1 -0
- metadata +137 -0
data/bin/AimsCalc
ADDED
@@ -0,0 +1,367 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#
|
4
|
+
# AimsCalc [geometry] [control]
|
5
|
+
#
|
6
|
+
# Author: Joshua Shapiro, 2012
|
7
|
+
# email: joshua.shapiro@gmail.com
|
8
|
+
#
|
9
|
+
# Generate a set of FHI-AIMS calculations from control and geometry files.
|
10
|
+
# If the user provides filename on the command line the calculation is generated,
|
11
|
+
# otherwise, the user is prompted for filenames.
|
12
|
+
#
|
13
|
+
|
14
|
+
begin
|
15
|
+
require 'aims_project'
|
16
|
+
require 'highline'
|
17
|
+
rescue
|
18
|
+
require 'rubygems'
|
19
|
+
require 'aims_project'
|
20
|
+
end
|
21
|
+
|
22
|
+
def usage
|
23
|
+
STDERR.puts <<-END_USAGE
|
24
|
+
usage: AimsCalc command [args]
|
25
|
+
Valid commands are:
|
26
|
+
create - Create a new calculation
|
27
|
+
restart - Restart an aborted or cancelled calculation using most recent geometry
|
28
|
+
rerun - Rerun a calculation using the original geometry and control
|
29
|
+
rename - Rename a control or geometry file and all dependent calculations
|
30
|
+
invalidate - Invalidate a geometry or control file and dependent calculations
|
31
|
+
hold - Place a STAGED calculation into a HOLD status
|
32
|
+
release - Release a calculation from HOLD, placing it back in STAGED status
|
33
|
+
setvar - Set a calculation variable
|
34
|
+
help cmd - For help on a given command
|
35
|
+
END_USAGE
|
36
|
+
end
|
37
|
+
|
38
|
+
def help(cmd)
|
39
|
+
case cmd
|
40
|
+
when /create/
|
41
|
+
puts <<-HELP
|
42
|
+
usage: AimsCalc create [geometry] [control]
|
43
|
+
Create and stage a new calculation.
|
44
|
+
* geometry is the name of a geometry file
|
45
|
+
* control is the name of a control file
|
46
|
+
|
47
|
+
Without arguments, the user will be prompted to select geometry and control files.
|
48
|
+
|
49
|
+
HELP
|
50
|
+
when /restart/
|
51
|
+
puts <<-HELP
|
52
|
+
usage: AimsCalc restart [calculation]
|
53
|
+
Restart an aborted or cancelled calculation using most recent available geometry.
|
54
|
+
* The name of a calculation
|
55
|
+
|
56
|
+
Without arguments, the user will be prompted to select a calculation.
|
57
|
+
|
58
|
+
HELP
|
59
|
+
when /status/
|
60
|
+
puts <<-HELP
|
61
|
+
usage: AimsCalc status
|
62
|
+
Currently just dumps all the status files
|
63
|
+
HELP
|
64
|
+
when /rerun/
|
65
|
+
puts <<-HELP
|
66
|
+
|
67
|
+
usage: AimsCalc rerun [calculation]
|
68
|
+
|
69
|
+
Use this to rerun a calculation for whatever reason. This will
|
70
|
+
set the calculation status back to staged. run cap aims:enqueue to
|
71
|
+
actually rerun the calculation.
|
72
|
+
HELP
|
73
|
+
when /rename/
|
74
|
+
puts <<-HELP
|
75
|
+
|
76
|
+
usage: AimsCalc rename [control or geometry]
|
77
|
+
|
78
|
+
Renames a control or geometry file and all dependent calculations.
|
79
|
+
HELP
|
80
|
+
when /invalidate/
|
81
|
+
puts <<-HELP
|
82
|
+
|
83
|
+
usage: AimsCalc invalidate [geometry or control]
|
84
|
+
|
85
|
+
Invalidate a geometry or control file. This will mark the geometry
|
86
|
+
or control file as well as any dependent calculations as INVALID.
|
87
|
+
A warning will be issued if the user tries to use the INVALID input file.
|
88
|
+
HELP
|
89
|
+
when /hold/
|
90
|
+
puts <<-HELP
|
91
|
+
|
92
|
+
usage: AimsCalc hold calculation
|
93
|
+
|
94
|
+
Place a calculation that is currently STAGED into a HOLD status. This means it will
|
95
|
+
not be QUEUED for calculation. Use 'release' to re-STAGE the calculation.
|
96
|
+
HELP
|
97
|
+
when /release/
|
98
|
+
puts <<-HELP
|
99
|
+
|
100
|
+
usage: AimsCalc release calculation
|
101
|
+
|
102
|
+
Set the status for a calculation that is currently on HOLD status to STAGED.
|
103
|
+
This means it will be scheduled for execution the next time enqueue is run.
|
104
|
+
HELP
|
105
|
+
|
106
|
+
when /setvar/
|
107
|
+
puts <<-HELP
|
108
|
+
|
109
|
+
usage: AimsCalc setvar var1=value1 var2=value2 ...
|
110
|
+
|
111
|
+
Set a project variable. These variables are available for use in
|
112
|
+
geometry and control files using embedded ruby with the @var syntax.
|
113
|
+
|
114
|
+
ex.
|
115
|
+
AimsCalc setvar lattice_const=5.65
|
116
|
+
|
117
|
+
Then in a geometry file
|
118
|
+
atom 0 0 0 Ga
|
119
|
+
atom <%= [@gaas_lattice_const/4 @gaas_lattice_const/4 @gaas_lattice_const/4].join(" ") %> As
|
120
|
+
|
121
|
+
HELP
|
122
|
+
|
123
|
+
else
|
124
|
+
usage
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
# Get the project associated with the current directory
|
129
|
+
# returns nil if unable to find a project
|
130
|
+
def project
|
131
|
+
project_obj_files = Dir["*.yaml"]
|
132
|
+
unless project_obj_files.empty?
|
133
|
+
AimsProject::Project.load(project_obj_files.first)
|
134
|
+
else
|
135
|
+
raise AimsProject::AimsProjectException.new("Sorry, I can't tell what project this is. Please move to the project root directory.")
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
# Parse command line arguments of the form a=1 b=2 into a hash
|
140
|
+
# suitable for evaluating in the project binding
|
141
|
+
def parse_vars(args)
|
142
|
+
vars = {}
|
143
|
+
|
144
|
+
# Condition format of input user variables
|
145
|
+
args.each{|arg|
|
146
|
+
if arg =~ /(.*)=(.*)/
|
147
|
+
# Split key=value pairs
|
148
|
+
symbol = $1
|
149
|
+
value = $2
|
150
|
+
# Prefix all variables with an @
|
151
|
+
sym = if symbol.to_s =~ /^@.*/
|
152
|
+
symbol.to_sym
|
153
|
+
else
|
154
|
+
("@" + symbol.to_s).to_sym
|
155
|
+
end
|
156
|
+
|
157
|
+
# Cast value to Float if applicable
|
158
|
+
val = if value =~ /^(\d+\.*\d*)$/
|
159
|
+
$1.to_f
|
160
|
+
elsif value =~ /"(.*)"/ or value =~ /'(.*)'/
|
161
|
+
$1
|
162
|
+
else
|
163
|
+
value
|
164
|
+
end
|
165
|
+
|
166
|
+
# Set the variable in the Vars hash
|
167
|
+
vars[sym] = val
|
168
|
+
end
|
169
|
+
}
|
170
|
+
vars
|
171
|
+
end
|
172
|
+
|
173
|
+
# Create a calculation from a geometry and control file.
|
174
|
+
# @param [String] geometry The name of a file that can be found in the geometry directory
|
175
|
+
# @param [String] control The name of a file that can be found in the control directory
|
176
|
+
# @param [Array<String>] args An array of string key-value pairs in the form of "key=value"
|
177
|
+
# These key-value pairs will be loaded as instance variables into the binding that
|
178
|
+
# is used to evaluate geometry and control.
|
179
|
+
def build_calculation(geometry, control, args)
|
180
|
+
begin
|
181
|
+
# a hash to store the user defined variables
|
182
|
+
vars = parse_vars(args)
|
183
|
+
# Load the project variables
|
184
|
+
p = project
|
185
|
+
calc = AimsProject::Calculation.create(p, geometry, control, vars)
|
186
|
+
puts "Created #{calc.calculation_directory}"
|
187
|
+
rescue
|
188
|
+
puts $!.message
|
189
|
+
puts $!.backtrace
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
# Generate a new calculation by calling Calculation::restart_relaxation
|
194
|
+
def restart_calculation(calculation)
|
195
|
+
calc = begin
|
196
|
+
AimsProject::Calculation.load(calculation)
|
197
|
+
rescue ObjectFileNotFoundException
|
198
|
+
calc_dir = File.join(AimsProject::CALCULATION_DIR, File.basename(calculation))
|
199
|
+
calc = AimsProject::Calculation.load(calc_dir)
|
200
|
+
end
|
201
|
+
newcalc = calc.restart_relaxation
|
202
|
+
puts "Created #{newcalc.name}"
|
203
|
+
end
|
204
|
+
|
205
|
+
# Print status information of each calculation
|
206
|
+
def calc_statuses
|
207
|
+
def date_str_fmt(dt)
|
208
|
+
case dt
|
209
|
+
when nil
|
210
|
+
"N/A"
|
211
|
+
when Date.today
|
212
|
+
"Today at " + dt.strftime("%H:%M")
|
213
|
+
when Date.today.prev_day
|
214
|
+
"Yesterday"
|
215
|
+
else
|
216
|
+
dt.strftime("%Y-%m-%d")
|
217
|
+
end
|
218
|
+
end
|
219
|
+
def duration_fmt(t)
|
220
|
+
if t < 2
|
221
|
+
"%0.2f hrs" % (t.to_f.abs*24.0)
|
222
|
+
else
|
223
|
+
"%i days ago" % t.round
|
224
|
+
end
|
225
|
+
end
|
226
|
+
def status_fmt(s)
|
227
|
+
color = case s
|
228
|
+
when AimsProject::RUNNING
|
229
|
+
:green
|
230
|
+
when AimsProject::COMPLETE
|
231
|
+
:yellow
|
232
|
+
when AimsProject::CANCELED
|
233
|
+
:red
|
234
|
+
else
|
235
|
+
nil
|
236
|
+
end
|
237
|
+
HighLine.color(s,color)
|
238
|
+
end
|
239
|
+
project_obj_files = Dir["*.yaml"]
|
240
|
+
project = AimsProject::Project.load(project_obj_files.first)
|
241
|
+
format = "%-40s\t%-30s\t%-15s\t%-15s\t%-15s\t%-15s"
|
242
|
+
puts format % ["GEOMETRY", "CONTROL", "STATUS", "CREATED_AT", "UPDATED_AT", "SINCE_UPDATE"]
|
243
|
+
project.calculations.sort{|a, b| a.updated_at <=> b.updated_at}.each{|c|
|
244
|
+
puts format % [c.geometry[0..40], c.control[0..30], status_fmt(c.status), date_str_fmt(c.created_at), date_str_fmt(c.updated_at), duration_fmt(DateTime.now - c.updated_at)]
|
245
|
+
}
|
246
|
+
end
|
247
|
+
|
248
|
+
# Place the specified calculations on HOLD status if they are staged.
|
249
|
+
def hold(calculation)
|
250
|
+
calc = get_calculation_from_string(calculation)
|
251
|
+
if calc.hold
|
252
|
+
puts "Calculation status set to #{calc.status}. Use AimsCalc release to revert to STAGED"
|
253
|
+
else
|
254
|
+
puts "Unable to set status of calculation to HOLD"
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
# Release a calculation from HOLD status
|
259
|
+
def release(calculation)
|
260
|
+
calc = get_calculation_from_string(calculation)
|
261
|
+
if calc.release
|
262
|
+
puts "Calculation status set to #{calc.status}."
|
263
|
+
else
|
264
|
+
puts "Unable to release calculation from HOLD"
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
# Set the calculation status back to staged
|
269
|
+
def rerun_calculation(calculation)
|
270
|
+
calc = begin
|
271
|
+
AimsProject::Calculation.load(calculation)
|
272
|
+
rescue ObjectFileNotFoundException
|
273
|
+
calc_dir = File.join(AimsProject::CALCULATION_DIR, File.basename(calculation))
|
274
|
+
calc = AimsProject::Calculation.load(calc_dir)
|
275
|
+
end
|
276
|
+
calc.status = AimsProject::STAGED
|
277
|
+
calc.save
|
278
|
+
puts "Calculation status set to STAGED. Run cap aims:enqueue to execute."
|
279
|
+
puts
|
280
|
+
end
|
281
|
+
|
282
|
+
def get_calculation_from_string(str)
|
283
|
+
calc = begin
|
284
|
+
AimsProject::Calculation.load(str)
|
285
|
+
rescue ObjectFileNotFoundException
|
286
|
+
calc_dir = File.join(AimsProject::CALCULATION_DIR, File.basename(str))
|
287
|
+
calc = AimsProject::Calculation.load(calc_dir)
|
288
|
+
end
|
289
|
+
calc
|
290
|
+
end
|
291
|
+
|
292
|
+
# Rename a geometry or control file and all dependent calculations
|
293
|
+
# @param file The name of the original file
|
294
|
+
# @param newname The new name for the file
|
295
|
+
def rename(file, newname)
|
296
|
+
raise "Sorry... 'AimsCalc rename' isn't implemented yet."
|
297
|
+
end
|
298
|
+
|
299
|
+
# Set project variables
|
300
|
+
def setvar(args)
|
301
|
+
vars = parse_vars(args)
|
302
|
+
p = project
|
303
|
+
vars.each{|sym, val|
|
304
|
+
p.instance_variable_set(sym, val)
|
305
|
+
puts "Setting #{sym} = #{val}"
|
306
|
+
}
|
307
|
+
p.save
|
308
|
+
end
|
309
|
+
|
310
|
+
# Invalidate each of the geometry or control inputs specified in arguments
|
311
|
+
def invalidate(args)
|
312
|
+
args.each {|arg|
|
313
|
+
files = Dir.glob(File.join(AimsProject::GEOMETRY_DIR, arg))
|
314
|
+
files += Dir.glob(File.join(AimsProject::CONTROL_DIR, arg))
|
315
|
+
files.each{|f|
|
316
|
+
# Write a note in file header
|
317
|
+
puts "I would invalidate #{f} here if I was implemented..."
|
318
|
+
# Find all the dependent calculations
|
319
|
+
|
320
|
+
# and set their status to invalid
|
321
|
+
|
322
|
+
}
|
323
|
+
}
|
324
|
+
end
|
325
|
+
|
326
|
+
# Run the desired command
|
327
|
+
begin
|
328
|
+
args = ARGV
|
329
|
+
cmd = args.shift
|
330
|
+
case cmd
|
331
|
+
when /create/
|
332
|
+
build_calculation(args[0], args[1], args[2..-1])
|
333
|
+
when /restart/
|
334
|
+
restart_calculation(args[0])
|
335
|
+
when /status/
|
336
|
+
calc_statuses
|
337
|
+
when /rerun/
|
338
|
+
rerun_calculation(args[0])
|
339
|
+
when /invalidate/
|
340
|
+
invalidate(args)
|
341
|
+
when /rename/
|
342
|
+
rename(args[0], args[1])
|
343
|
+
when /hold/
|
344
|
+
hold(args)
|
345
|
+
when /release/
|
346
|
+
release(args)
|
347
|
+
when /setvar/
|
348
|
+
setvar(args)
|
349
|
+
when /help/
|
350
|
+
help(args[0])
|
351
|
+
else
|
352
|
+
usage
|
353
|
+
end
|
354
|
+
rescue AimsProject::AimsProjectException => ex
|
355
|
+
STDERR.puts ex.message
|
356
|
+
rescue => error
|
357
|
+
STDERR.puts
|
358
|
+
STDERR.puts "Sorry, something went wrong. Please send the following information to joshua.shapiro@gmail.com"
|
359
|
+
STDERR.puts
|
360
|
+
STDERR.puts "FILE: #{__FILE__}"
|
361
|
+
STDERR.puts "CMD: #{cmd}"
|
362
|
+
STDERR.puts "ARGS: #{args.join(" ")}"
|
363
|
+
STDERR.puts "ERROR: " + error.message
|
364
|
+
STDERR.print "\t" + error.backtrace.slice(0..5).join("\n\t")
|
365
|
+
STDERR.puts
|
366
|
+
STDERR.puts
|
367
|
+
end
|
data/bin/AimsProject
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'aims_project'
|
3
|
+
require 'fileutils'
|
4
|
+
require 'highline'
|
5
|
+
|
6
|
+
# Initialize an AimsProject
|
7
|
+
# Create a directory named by the project
|
8
|
+
# and generate the AimsProjectInfo.yaml file
|
9
|
+
|
10
|
+
ui = HighLine.new
|
11
|
+
skeleton_dir = File.join(Dir.home, ".aims_project")
|
12
|
+
|
13
|
+
unless File.exists?(skeleton_dir)
|
14
|
+
ui.say <<-EOF
|
15
|
+
|
16
|
+
It looks like this is the first time you are running AimsProject.
|
17
|
+
|
18
|
+
I can create the directory $HOME/.aims_project which will be the
|
19
|
+
template for all of your future projects. Feel free to customize the
|
20
|
+
files in this directory to suit your needs. In particular, you will
|
21
|
+
want to customize 'Capfile' and 'aims.sh'. And you may want to add
|
22
|
+
variables that should be available to any project in 'project_variables.rb'
|
23
|
+
|
24
|
+
EOF
|
25
|
+
|
26
|
+
# Copy the skeleton directory tasks into config
|
27
|
+
script_dir = File.join(File.dirname(File.expand_path(__FILE__)), '..', 'skeleton')
|
28
|
+
|
29
|
+
if ui.agree("Can I create #{Dir.home}/.aims_project?")
|
30
|
+
# Create the skeleton directory in $HOME/.aims_project
|
31
|
+
Dir.mkdir skeleton_dir
|
32
|
+
FileUtils.cp_r(File.join(script_dir, '.'), skeleton_dir)
|
33
|
+
else
|
34
|
+
ui.say("Ok, maybe next time.")
|
35
|
+
skeleton_dir = script_dir
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Set the project name and direcory
|
40
|
+
projectName = ARGV[0]
|
41
|
+
unless projectName
|
42
|
+
projectName = ui.ask("Please specify the name of the project: ", String) {|q| q.whitespace = :remove}.to_s
|
43
|
+
end
|
44
|
+
|
45
|
+
projectDir = projectName
|
46
|
+
|
47
|
+
if project = AimsProject::Project.create(projectName)
|
48
|
+
|
49
|
+
ui.say "Creating #{projectDir}..."
|
50
|
+
|
51
|
+
# save the project into a directory named after the project
|
52
|
+
project.save(projectDir)
|
53
|
+
|
54
|
+
# Copy the skeleton directory tasks into config
|
55
|
+
FileUtils.cp_r(File.join(skeleton_dir, '.'), projectDir)
|
56
|
+
|
57
|
+
|
58
|
+
# Generate the default Capfile
|
59
|
+
capfile = ""
|
60
|
+
File.open(File.join(projectDir, "Capfile"), 'r') do |capfile_template|
|
61
|
+
capfile_template.each_line do |line|
|
62
|
+
line.sub!(/__PROJECT_DIR__/, projectDir)
|
63
|
+
line.sub!(/__PROJECT_NAME__/, projectName)
|
64
|
+
capfile << line
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
File.open(File.join(projectDir, "Capfile"), 'w') do |f|
|
69
|
+
f.puts capfile
|
70
|
+
end
|
71
|
+
|
72
|
+
STDOUT.puts <<-EOL
|
73
|
+
|
74
|
+
Done creating the aims project #{projectName}. Here are the steps to get started.
|
75
|
+
1) Customize the variables in #{File.join(projectDir, "Capfile")}
|
76
|
+
2) Add geometry files to the directory #{File.join(projectDir, AimsProject::GEOMETRY_DIR)}
|
77
|
+
3) Add control files to the directory #{File.join(projectDir, AimsProject::CONTROL_DIR)}
|
78
|
+
4) Generate a calculation with the command:
|
79
|
+
AimsCalc create [geometry] [control]
|
80
|
+
5) Execute the calculations with the command:
|
81
|
+
cap aims:enqueue
|
82
|
+
|
83
|
+
EOL
|
84
|
+
|
85
|
+
else
|
86
|
+
STDERR.puts "Error creating project."
|
87
|
+
STDERR.puts $!.message
|
88
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "rubygems"
|
4
|
+
|
5
|
+
require "wx"
|
6
|
+
require "erb"
|
7
|
+
require "gl"
|
8
|
+
require "glu"
|
9
|
+
|
10
|
+
require 'aims'
|
11
|
+
require 'aims_project'
|
12
|
+
require 'aims_project/material.rb'
|
13
|
+
require 'aims_project/atom.rb'
|
14
|
+
require 'aims_project/inspector.rb'
|
15
|
+
require 'aims_project/crystal_viewer.rb'
|
16
|
+
require 'aims_project/geometry_editor.rb'
|
17
|
+
require 'aims_project/geometry_console.rb'
|
18
|
+
require 'aims_project/project_tree.rb'
|
19
|
+
require 'aims_project/calculation_tree.rb'
|
20
|
+
require 'aims_project/app_controller.rb'
|
21
|
+
require 'aims_project/geometry_window.rb'
|
22
|
+
require 'aims_project/calculation_window.rb'
|
23
|
+
require 'aims_project/thread_callback_event.rb'
|
24
|
+
require 'aims_project/crystal_viewer_options.rb'
|
25
|
+
|
26
|
+
controller = AimsProject::AppController.new
|
27
|
+
|
28
|
+
unless __FILE__.nil?
|
29
|
+
cwd = File.expand_path(".")
|
30
|
+
controller.working_dir = cwd
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
# project_obj_files = Dir["*.yaml"]
|
35
|
+
# controller.project = AimsProject::Project.load(project_obj_files.first) unless project_obj_files.empty?
|
36
|
+
AimsProject::ThreadCallbackEvent.set_event_type(Wx::Event.new_event_type)
|
37
|
+
Wx::EvtHandler.register_class(AimsProject::ThreadCallbackEvent, AimsProject::ThreadCallbackEvent.event_type, "evt_thread_callback", 0)
|
38
|
+
|
39
|
+
controller.main_loop
|
@@ -0,0 +1,42 @@
|
|
1
|
+
|
2
|
+
module AimsProject
|
3
|
+
class AimsProjectException < StandardError
|
4
|
+
end
|
5
|
+
|
6
|
+
class InvalidFilenameException < AimsProjectException
|
7
|
+
def initialize(filename)
|
8
|
+
if filename.nil?
|
9
|
+
super "No filename specified"
|
10
|
+
else
|
11
|
+
super "The filename #{filename} is invalid."
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class ObjectFileNotFoundException < AimsProjectException
|
17
|
+
def initialize(filename)
|
18
|
+
super "The serialized yaml file was not found: #{filename}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class CorruptObjectFileException < AimsProjectException
|
23
|
+
def initialize(filename)
|
24
|
+
super "The serialized yaml file is corrupt: #{filename}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class GeometryValidationException < AimsProjectException
|
29
|
+
attr_reader :violations
|
30
|
+
def initialize(violations)
|
31
|
+
@violations = violations
|
32
|
+
super "The Geometry failed validation."
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class GeometryEvaluationException < AimsProjectException
|
37
|
+
def initialize
|
38
|
+
super "Error evaluating geometry"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module AimsProject
|
2
|
+
|
3
|
+
# A class that encapsulates the Aims::Geometry and other
|
4
|
+
# state information important for AimsProject
|
5
|
+
class AimsProjectGeometry
|
6
|
+
|
7
|
+
# Boolean flag indicating whether the atoms should be displaced to all lie
|
8
|
+
# within the unit cell
|
9
|
+
attr_accessor :correct_geometry
|
10
|
+
|
11
|
+
# The filename defining this geometry
|
12
|
+
attr_reader :filename
|
13
|
+
|
14
|
+
def initialize(file)
|
15
|
+
@filename = file
|
16
|
+
@geometry_original = Aims::GeometryParser.parse(@filename)
|
17
|
+
end
|
18
|
+
|
19
|
+
def geometry
|
20
|
+
if self.correct_geometry
|
21
|
+
geometry_corrected
|
22
|
+
else
|
23
|
+
geometry_original
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def geometry_corrected
|
28
|
+
if @geometry_corrected.nil?
|
29
|
+
@geometry_corrected = @geometry_original.correct
|
30
|
+
end
|
31
|
+
@geometry_corrected
|
32
|
+
end
|
33
|
+
|
34
|
+
def geometry_original
|
35
|
+
@geometry_original
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_s
|
39
|
+
@filename
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
def save
|
44
|
+
unless @filename
|
45
|
+
raise InvalidFilenameException
|
46
|
+
end
|
47
|
+
raise "AimsProjectGeometry.save is not yet implemented"
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|