/
main.py
160 lines (134 loc) · 4.62 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#!/usr/bin/env python
#
# mcmandelbrot
#
# An example package for AsynQueue:
# Asynchronous task queueing based on the Twisted framework, with task
# prioritization and a powerful worker interface.
#
# Copyright (C) 2015 by Edwin A. Suominen,
# http://edsuom.com/AsynQueue
#
# See edsuom.com for API documentation as well as information about
# Ed's background and other projects, software and otherwise.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the
# License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an "AS
# IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
# express or implied. See the License for the specific language
# governing permissions and limitations under the License.
"""
An example of C{AsynQueue} in action. Can be fun to play with if
you have a multicore CPU. You will need the following packages, which
you can get via C{pip install}: C{weave} (part of SciPy); C{numpy}
(part of SciPy); C{matplotlib}; and of course C{asynqueue}.
B{TODO:} If you want to run with the Qt GUI (-g option), you also need
C{qt4reactor} and C{pyqt4}.
Command line usage::
mcmandelbrot
[-d <description>] [-N <iterations>]
[-o <imageFile>]
[-g] [-s] [-a <aspect ratio>]
Nx cr ci crPM [ciPM]
Writes PNG image to stdout unless B{-o} is set, then saves it to
I{imageFile}. In that case, prints some stats about the
multiprocessing computation to I{stdout}.
To see an overview displayed with ImageMagick's I{display} command::
mcmandelbrot 2000 -0.630 0 1.4 1.2 |display
Write a detailed view to the image I{detail.png}::
mcmandelbrot -o detail.png 3000 -0.73249 +0.21653 0.0112
"""
import sys
from twisted.internet import defer, reactor
from mcmandelbrot import runner, wire
def run(*args, **kw):
"""
Call with::
[-d, <description>,] [-N, <values>,]
[-o, <imageFile>,]
[-g,] [-s,]
Nx, cr, ci, crPM, [ciPM]
Writes PNG image to stdout unless -o is set, then saves it to
C{imageFile}. In that case, prints some stats about the
multiprocessing computation to stdout.
Options-as-arguments:
- B{d}: An endpoint I{description} of a server running a
L{wire.server}.
- B{s}: Show image (B{TODO})
@keyword N_values: Integer number of possible values for
Mandelbrot points during iteration. Can set with the C{-N
values} arg instead.
@keyword ignoreReactor: Set C{True} to let somebody else start and
stop the reactor.
"""
@defer.inlineCallbacks
def reallyRun():
if description:
myRunner = wire.RemoteRunner(description)
yield myRunner.setup(N_values=N_values)
else:
myRunner = runner.Runner(N_values, stats)
runInfo = yield myRunner.run(fh, Nx, cr, ci, crPM, ciPM)
if stats:
yield myRunner.showStats(runInfo)
yield myRunner.shutdown()
if not ignoreReactor:
reactor.stop()
defer.returnValue(runInfo)
def getOpt(opt, default=None):
optCode = "-{}".format(opt)
if optCode in args:
k = args.index(optCode)
args.pop(k)
if default is None:
return
optType = type(default)
return optType(args.pop(k))
return default
ignoreReactor = kw.pop('ignoreReactor', False)
if not args:
args = sys.argv[1:]
args = list(args)
show = getOpt('s')
N_values = getOpt('N', 2000)
fileName = getOpt('o', "")
description = getOpt('d', "")
useGUI = getOpt('g')
if fileName:
stats = True
fh = open(fileName, 'w')
else:
stats = False
fh = sys.stdout
if len(args) < 4:
print(
"Usage: [-N values] "+\
"[-o imageFile] [-d description] [-g] [-s] " +\
"N cr ci crPM [ciPM]")
sys.exit(1)
Nx = int(args[0])
cr, ci, crPM = [float(x) for x in args[1:4]]
ciPM = float(args[4]) if len(args) > 4 else crPM
if useGUI:
raise NotImplementedError("GUI not yet implemented")
# TODO
from PyQt4 import QtGui
import qt4reactor
import gui
app = QtGui.QApplication(sys.argv)
qt4reactor.install()
w = gui.MainWindow(Nx, cr, ci, crPM)
reactor.run()
elif ignoreReactor:
return reallyRun()
else:
reactor.callWhenRunning(reallyRun)
reactor.run()
if __name__ == '__main__':
run()