pygmi 2.2.7__zip

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.
Files changed (106) hide show
  1. pygmi-2.2.7/LICENSE.txt +623 -0
  2. pygmi-2.2.7/MANIFEST.in +7 -0
  3. pygmi-2.2.7/PKG-INFO +47 -0
  4. pygmi-2.2.7/README.md +55 -0
  5. pygmi-2.2.7/README.rst +20 -0
  6. pygmi-2.2.7/log.txt +242 -0
  7. pygmi-2.2.7/pygmi/__init__.py +22 -0
  8. pygmi-2.2.7/pygmi/clust/__init__.py +4 -0
  9. pygmi-2.2.7/pygmi/clust/crisp_clust.py +708 -0
  10. pygmi-2.2.7/pygmi/clust/datatypes.py +65 -0
  11. pygmi-2.2.7/pygmi/clust/fuzzy_clust.py +906 -0
  12. pygmi-2.2.7/pygmi/clust/graphs.py +421 -0
  13. pygmi-2.2.7/pygmi/clust/graphtool.py +667 -0
  14. pygmi-2.2.7/pygmi/clust/menu.py +139 -0
  15. pygmi-2.2.7/pygmi/clust/var_ratio.py +92 -0
  16. pygmi-2.2.7/pygmi/clust/xie_beni.py +93 -0
  17. pygmi-2.2.7/pygmi/helpdocs/linepointer.png +0 -0
  18. pygmi-2.2.7/pygmi/helpdocs/pygmi.main.html +31 -0
  19. pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.ddisp.html +15 -0
  20. pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.iodefs.exportkmz.html +13 -0
  21. pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.iodefs.importpicture.html +16 -0
  22. pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.layer.html +17 -0
  23. pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.mext.html +44 -0
  24. pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.misc.rangedcopy.html +16 -0
  25. pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.param.html +37 -0
  26. pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.prof.html +32 -0
  27. pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.pview.html +26 -0
  28. pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.cooper.gradients.html +14 -0
  29. pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.cooper.tilt.html +14 -0
  30. pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.cooper.visibility.html +14 -0
  31. pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.dataprep.datagrid.html +13 -0
  32. pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.dataprep.datamerge.html +11 -0
  33. pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.dataprep.datareproj.html +11 -0
  34. pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.dataprep.rtp.html +14 -0
  35. pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.ginterp.html +31 -0
  36. pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.igrf.html +20 -0
  37. pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.normalisation.html +14 -0
  38. pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.smooth.html +22 -0
  39. pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.tiltdepth.html +20 -0
  40. pygmi-2.2.7/pygmi/images/Help.png +0 -0
  41. pygmi-2.2.7/pygmi/images/bringtofront.png +0 -0
  42. pygmi-2.2.7/pygmi/images/cgs2.emf +0 -0
  43. pygmi-2.2.7/pygmi/images/delete.png +0 -0
  44. pygmi-2.2.7/pygmi/images/linepointer.png +0 -0
  45. pygmi-2.2.7/pygmi/images/logo256.ico +0 -0
  46. pygmi-2.2.7/pygmi/images/logo256.png +0 -0
  47. pygmi-2.2.7/pygmi/images/pointer.png +0 -0
  48. pygmi-2.2.7/pygmi/images/pygmi.png +0 -0
  49. pygmi-2.2.7/pygmi/images/sendtoback.png +0 -0
  50. pygmi-2.2.7/pygmi/main.py +1037 -0
  51. pygmi-2.2.7/pygmi/menu_default.py +327 -0
  52. pygmi-2.2.7/pygmi/misc.py +147 -0
  53. pygmi-2.2.7/pygmi/pfmod/__init__.py +6 -0
  54. pygmi-2.2.7/pygmi/pfmod/cubes.py +1488 -0
  55. pygmi-2.2.7/pygmi/pfmod/datatypes.py +292 -0
  56. pygmi-2.2.7/pygmi/pfmod/grvmag3d.py +1265 -0
  57. pygmi-2.2.7/pygmi/pfmod/iodefs.py +1001 -0
  58. pygmi-2.2.7/pygmi/pfmod/menu.py +107 -0
  59. pygmi-2.2.7/pygmi/pfmod/misc.py +301 -0
  60. pygmi-2.2.7/pygmi/pfmod/pfmod.py +248 -0
  61. pygmi-2.2.7/pygmi/pfmod/tab_ddisp.py +425 -0
  62. pygmi-2.2.7/pygmi/pfmod/tab_layer.py +490 -0
  63. pygmi-2.2.7/pygmi/pfmod/tab_mext.py +544 -0
  64. pygmi-2.2.7/pygmi/pfmod/tab_param.py +548 -0
  65. pygmi-2.2.7/pygmi/pfmod/tab_prof.py +946 -0
  66. pygmi-2.2.7/pygmi/pfmod/tab_pview.py +740 -0
  67. pygmi-2.2.7/pygmi/raster/IGRF11.COF +1635 -0
  68. pygmi-2.2.7/pygmi/raster/__init__.py +14 -0
  69. pygmi-2.2.7/pygmi/raster/cooper.py +718 -0
  70. pygmi-2.2.7/pygmi/raster/dataprep.py +1640 -0
  71. pygmi-2.2.7/pygmi/raster/datatypes.py +123 -0
  72. pygmi-2.2.7/pygmi/raster/equation_editor.py +256 -0
  73. pygmi-2.2.7/pygmi/raster/ginterp.py +1901 -0
  74. pygmi-2.2.7/pygmi/raster/graphs.py +531 -0
  75. pygmi-2.2.7/pygmi/raster/igrf.py +860 -0
  76. pygmi-2.2.7/pygmi/raster/iodefs.py +813 -0
  77. pygmi-2.2.7/pygmi/raster/menu.py +307 -0
  78. pygmi-2.2.7/pygmi/raster/normalisation.py +187 -0
  79. pygmi-2.2.7/pygmi/raster/show_table.py +245 -0
  80. pygmi-2.2.7/pygmi/raster/smooth.py +406 -0
  81. pygmi-2.2.7/pygmi/raster/tiltdepth.py +590 -0
  82. pygmi-2.2.7/pygmi/seis/__init__.py +0 -0
  83. pygmi-2.2.7/pygmi/seis/beachball.py +751 -0
  84. pygmi-2.2.7/pygmi/seis/datatypes.py +605 -0
  85. pygmi-2.2.7/pygmi/seis/del_rec.py +410 -0
  86. pygmi-2.2.7/pygmi/seis/iodefs.py +1261 -0
  87. pygmi-2.2.7/pygmi/seis/menu.py +136 -0
  88. pygmi-2.2.7/pygmi/seis/scan_imp.py +795 -0
  89. pygmi-2.2.7/pygmi/test/__init__.py +6 -0
  90. pygmi-2.2.7/pygmi/test/pfmod.py +212 -0
  91. pygmi-2.2.7/pygmi/test/tests.py +39 -0
  92. pygmi-2.2.7/pygmi/vector/__init__.py +7 -0
  93. pygmi-2.2.7/pygmi/vector/datatypes.py +74 -0
  94. pygmi-2.2.7/pygmi/vector/graphs.py +443 -0
  95. pygmi-2.2.7/pygmi/vector/iodefs.py +345 -0
  96. pygmi-2.2.7/pygmi/vector/menu.py +127 -0
  97. pygmi-2.2.7/pygmi.egg-info/PKG-INFO +47 -0
  98. pygmi-2.2.7/pygmi.egg-info/SOURCES.txt +105 -0
  99. pygmi-2.2.7/pygmi.egg-info/dependency_links.txt +1 -0
  100. pygmi-2.2.7/pygmi.egg-info/entry_points.txt +3 -0
  101. pygmi-2.2.7/pygmi.egg-info/not-zip-safe +1 -0
  102. pygmi-2.2.7/pygmi.egg-info/requires.txt +7 -0
  103. pygmi-2.2.7/pygmi.egg-info/top_level.txt +1 -0
  104. pygmi-2.2.7/quickstart.py +35 -0
  105. pygmi-2.2.7/setup.cfg +8 -0
  106. pygmi-2.2.7/setup.py +80 -0
@@ -0,0 +1,443 @@
1
+ # -----------------------------------------------------------------------------
2
+ # Name: graphs.py (part of PyGMI)
3
+ #
4
+ # Author: Patrick Cole
5
+ # E-Mail: pcole@geoscience.org.za
6
+ #
7
+ # Copyright: (c) 2013 Council for Geoscience
8
+ # Licence: GPL-3.0
9
+ #
10
+ # This file is part of PyGMI
11
+ #
12
+ # PyGMI is free software: you can redistribute it and/or modify
13
+ # it under the terms of the GNU General Public License as published by
14
+ # the Free Software Foundation, either version 3 of the License, or
15
+ # (at your option) any later version.
16
+ #
17
+ # PyGMI is distributed in the hope that it will be useful,
18
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
19
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
+ # GNU General Public License for more details.
21
+ #
22
+ # You should have received a copy of the GNU General Public License
23
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
24
+ # -----------------------------------------------------------------------------
25
+ """ Plot Vector Data using Matplotlib """
26
+
27
+ import numpy as np
28
+ from PyQt4 import QtGui, QtCore
29
+ import matplotlib.pyplot as plt
30
+ import matplotlib.collections as mc
31
+ from matplotlib.backends.backend_qt4agg import FigureCanvas
32
+ from matplotlib.figure import Figure
33
+ from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as \
34
+ NavigationToolbar
35
+
36
+
37
+ class GraphWindow(QtGui.QDialog):
38
+ """Graph Window - Main QT Dialog class for graphs."""
39
+ def __init__(self, parent=None):
40
+ QtGui.QDialog.__init__(self, parent=None)
41
+ self.parent = parent
42
+
43
+ self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
44
+ self.setWindowTitle("Graph Window")
45
+
46
+ vbl = QtGui.QVBoxLayout(self) # self is where layout is assigned
47
+ self.hbl = QtGui.QHBoxLayout()
48
+ self.mmc = MyMplCanvas(self)
49
+ mpl_toolbar = NavigationToolbar(self.mmc, self.parent)
50
+
51
+ self.combobox1 = QtGui.QComboBox()
52
+ self.combobox2 = QtGui.QComboBox()
53
+ self.spinbox = QtGui.QSpinBox()
54
+ self.label1 = QtGui.QLabel()
55
+ self.label2 = QtGui.QLabel()
56
+ self.label3 = QtGui.QLabel()
57
+
58
+ self.label1.setText('Bands:')
59
+ self.label2.setText('Bands:')
60
+ self.label3.setText('Value:')
61
+
62
+ self.hbl.addWidget(self.label1)
63
+ self.hbl.addWidget(self.combobox1)
64
+ self.hbl.addWidget(self.label2)
65
+ self.hbl.addWidget(self.combobox2)
66
+ self.hbl.addWidget(self.label3)
67
+ self.hbl.addWidget(self.spinbox)
68
+
69
+ vbl.addWidget(self.mmc)
70
+ vbl.addWidget(mpl_toolbar)
71
+ vbl.addLayout(self.hbl)
72
+
73
+ self.setFocus()
74
+
75
+ self.combobox1.currentIndexChanged.connect(self.change_band)
76
+ self.combobox2.currentIndexChanged.connect(self.change_band)
77
+ self.spinbox.valueChanged.connect(self.change_band)
78
+
79
+ def change_band(self):
80
+ """Combo box to choose band """
81
+ pass
82
+
83
+
84
+ class MyMplCanvas(FigureCanvas):
85
+ """
86
+ MPL Canvas class.
87
+
88
+ This routine will also allow the pciking and movement of nodes of data."""
89
+ def __init__(self, parent=None):
90
+ # figure stuff
91
+ fig = Figure()
92
+ self.axes = fig.add_subplot(111)
93
+ self.line = None
94
+ self.ind = None
95
+ self.background = None
96
+ self.parent = parent
97
+
98
+ FigureCanvas.__init__(self, fig)
99
+
100
+ self.figure.canvas.mpl_connect('pick_event', self.onpick)
101
+ self.figure.canvas.mpl_connect('button_release_event',
102
+ self.button_release_callback)
103
+ self.figure.canvas.mpl_connect('motion_notify_event',
104
+ self.motion_notify_callback)
105
+
106
+ def button_release_callback(self, event):
107
+ """mouse button release callback """
108
+ if event.inaxes is None:
109
+ return
110
+ if event.button != 1:
111
+ return
112
+ self.ind = None
113
+
114
+ def motion_notify_callback(self, event):
115
+ """move mouse callback """
116
+ if event.inaxes is None:
117
+ return
118
+ if event.button != 1:
119
+ return
120
+ if self.ind is None:
121
+ return
122
+
123
+ dtmp = self.line.get_data()
124
+ dtmp[1][self.ind] = event.ydata
125
+ self.line.set_data(dtmp[0], dtmp[1])
126
+
127
+ self.figure.canvas.restore_region(self.background)
128
+ self.axes.draw_artist(self.line)
129
+ # self.figure.canvas.blit(self.axes.bbox)
130
+ self.figure.canvas.update()
131
+
132
+ def onpick(self, event):
133
+ """Picker event """
134
+ if event.mouseevent.inaxes is None:
135
+ return
136
+ if event.mouseevent.button != 1:
137
+ return
138
+ if event.artist != self.line:
139
+ return True
140
+
141
+ self.ind = event.ind
142
+ self.ind = self.ind[len(self.ind) / 2] # get center-ish value
143
+
144
+ return True
145
+
146
+ def update_line(self, data, ival):
147
+ """
148
+ Update the plot from point data.
149
+
150
+ Parameters
151
+ ----------
152
+ data1 : PData object
153
+ Point data
154
+ data2 : PData object
155
+ Point Data
156
+ """
157
+
158
+ data1 = data[ival]
159
+
160
+ self.figure.clear()
161
+
162
+ ax1 = self.figure.add_subplot(3, 1, 1)
163
+ ax1.set_title(data1.dataid)
164
+ self.axes = ax1
165
+
166
+ ax2 = self.figure.add_subplot(3, 1, 2, sharex=ax1)
167
+ ax2.set_title('Normalised stacked graphs')
168
+ ax2.set_xlabel('sample number')
169
+ ax2.set_ylabel('normalised value')
170
+
171
+ ax1.set_xlabel('sample number')
172
+ ax1.set_ylabel('value')
173
+
174
+ self.figure.canvas.draw()
175
+ self.background = self.figure.canvas.copy_from_bbox(ax1.bbox)
176
+
177
+ for i in data:
178
+ tmp = (i.zdata-i.zdata.min())/i.zdata.ptp()
179
+ ax2.plot(tmp, label=i.dataid)
180
+ ax2.set_ylim([-.1, 1.1])
181
+ ax2.legend(bbox_to_anchor=(0., -1.7, 1., -.7), loc=3, ncol=2,
182
+ mode='expand', borderaxespad=0., title='Legend')
183
+ self.line, = ax1.plot(data1.zdata, '.-', picker=5)
184
+ self.figure.tight_layout()
185
+ self.figure.canvas.draw()
186
+
187
+ def update_vector(self, data):
188
+ """
189
+ Update the plot from vactor data
190
+
191
+ Parameters
192
+ ----------
193
+ data : VData
194
+ Vector data. It can either be 'Line' or 'Poly' and typically is
195
+ imported from a shapefile.
196
+ """
197
+ self.figure.clear()
198
+
199
+ self.axes = self.figure.add_subplot(1, 1, 1)
200
+
201
+ if data.dtype == 'Line' or data.dtype == 'Poly':
202
+ lcol = mc.LineCollection(data.crds)
203
+ self.axes.add_collection(lcol)
204
+ self.axes.autoscale()
205
+ self.axes.axis('equal')
206
+
207
+ elif data.dtype == 'Point':
208
+ tmp = np.array(data.crds)
209
+ tmp.shape = (tmp.shape[0], tmp.shape[-1])
210
+ self.axes.plot(tmp[:, 0], tmp[:, 1], 'go')
211
+
212
+ self.figure.canvas.draw()
213
+
214
+ def update_rose(self, data, rtype, nbins=8):
215
+ """
216
+ Update the rose diagram plot using vector data.
217
+
218
+ Parameters
219
+ ----------
220
+ data : VData
221
+ Vector data. It should be 'Line'
222
+ rtype : int
223
+ Rose diagram type. Can be either 0 or 1.
224
+ nbins : int, optional
225
+ Number of bins used in rose diagram.
226
+ """
227
+ self.figure.clear()
228
+
229
+ ax1 = self.figure.add_subplot(121, polar=True)
230
+ # ax1.set_title('Rose')
231
+ ax1.set_theta_direction(-1)
232
+ ax1.set_theta_zero_location('N')
233
+ ax1.yaxis.set_ticklabels([])
234
+
235
+ self.axes = ax1
236
+
237
+ ax2 = self.figure.add_subplot(1, 2, 2)
238
+ # ax2.set_title('Lineaments')
239
+ # ax2.axis('equal')
240
+ ax2.set_aspect('equal')
241
+
242
+ fangle = []
243
+ fcnt = []
244
+ flen = []
245
+ allcrds = data.crds
246
+
247
+ for pnts in data.crds:
248
+ pnts = np.transpose(pnts)
249
+ xtmp = pnts[0, 1:]-pnts[0, :-1]
250
+ ytmp = pnts[1, 1:]-pnts[1, :-1]
251
+ ftmp = np.arctan2(xtmp, ytmp)
252
+ ftmp[ftmp < 0] += 2*np.pi
253
+ ftmp[ftmp > np.pi] -= np.pi
254
+ ltmp = np.sqrt(xtmp**2+ytmp**2)
255
+
256
+ fangle += [np.sum(ftmp*ltmp)/ltmp.sum()]
257
+ fcnt += ftmp.tolist()
258
+ flen += ltmp.tolist()
259
+
260
+ fangle = np.array(fangle)
261
+ fcnt = np.array(fcnt)
262
+ flen = np.array(flen)
263
+ bwidth = np.pi/nbins
264
+ bcols = plt.cm.Set1(np.arange(nbins)/nbins)
265
+ np.random.shuffle(bcols)
266
+
267
+ if rtype == 0:
268
+ # Draw rose diagram base on one angle per linear feature
269
+
270
+ radii, theta = np.histogram(fangle, bins=np.arange(0, np.pi,
271
+ bwidth))
272
+ xtheta = theta[:-1] # +(theta[1]-theta[0])/2
273
+ bcols2 = bcols[(xtheta/bwidth).astype(int)]
274
+ ax1.bar(xtheta, radii, width=bwidth, color=bcols2)
275
+ ax1.bar(xtheta+np.pi, radii, width=bwidth, color=bcols2)
276
+
277
+ bcols2 = bcols[(fangle/bwidth).astype(int)]
278
+ lcol = mc.LineCollection(allcrds, color=bcols2)
279
+ ax2.add_collection(lcol)
280
+ ax2.autoscale(enable=True, tight=True)
281
+
282
+ else:
283
+ # Draw rose diagram base on one angle per linear segment, normed
284
+ radii, theta = histogram(fcnt, y=flen, xmin=0., xmax=np.pi,
285
+ bins=nbins)
286
+ xtheta = theta[:-1]
287
+ bcols2 = bcols[(xtheta/bwidth).astype(int)]
288
+ ax1.bar(xtheta, radii, width=bwidth, color=bcols2)
289
+ ax1.bar(xtheta+np.pi, radii, width=bwidth, color=bcols2)
290
+
291
+ bcols2 = bcols[(fcnt/bwidth).astype(int)]
292
+ lcol = mc.LineCollection(allcrds, color=bcols2)
293
+ ax2.add_collection(lcol)
294
+ ax2.autoscale(enable=True, tight=True)
295
+
296
+ self.figure.canvas.draw()
297
+
298
+
299
+ class PlotPoints(GraphWindow):
300
+ """ Plot Raster Class """
301
+ def __init__(self, parent):
302
+ GraphWindow.__init__(self, parent)
303
+ self.indata = {}
304
+ self.parent = parent
305
+ self.spinbox.hide()
306
+ self.label3.hide()
307
+ self.combobox2.hide()
308
+ self.label2.hide()
309
+
310
+ def change_band(self):
311
+ """ Combo box to choose band """
312
+ data = self.indata['Point']
313
+ i = self.combobox1.currentIndex()
314
+ # j = self.combobox2.currentIndex()
315
+ self.mmc.update_line(data, i)
316
+
317
+ def run(self):
318
+ """ Run """
319
+ self.show()
320
+ data = self.indata['Point']
321
+ for i in data:
322
+ self.combobox1.addItem(i.dataid)
323
+ self.combobox2.addItem(i.dataid)
324
+
325
+ self.label1.setText('Editable Profile:')
326
+ self.label2.setText('Normalised Stacked Profile:')
327
+ self.combobox1.setCurrentIndex(0)
328
+ self.combobox2.setCurrentIndex(1)
329
+
330
+
331
+ class PlotRose(GraphWindow):
332
+ """ Plot Raster Class """
333
+ def __init__(self, parent):
334
+ GraphWindow.__init__(self, parent)
335
+ self.indata = {}
336
+ self.parent = parent
337
+ self.combobox2.hide()
338
+ self.label2.hide()
339
+ self.spinbox.setValue(8)
340
+ self.spinbox.setMinimum(2)
341
+ self.spinbox.setMaximum(360)
342
+ self.setWindowTitle("Rose Diagram")
343
+
344
+ def change_band(self):
345
+ """ Combo box to choose band """
346
+ if 'Vector' not in self.indata:
347
+ return
348
+ data = self.indata['Vector']
349
+ i = self.combobox1.currentIndex()
350
+ if data.dtype == 'Line':
351
+ self.mmc.update_rose(data, i, self.spinbox.value())
352
+
353
+ def run(self):
354
+ """ Run """
355
+ self.show()
356
+ self.combobox1.addItem('Average Angle per Feature')
357
+ self.combobox1.addItem('Angle per segment in Feature')
358
+ self.label1.setText('Rose Diagram Type:')
359
+ self.combobox1.setCurrentIndex(0)
360
+
361
+
362
+ class PlotVector(GraphWindow):
363
+ """ Plot Raster Class """
364
+ def __init__(self, parent):
365
+ GraphWindow.__init__(self, parent)
366
+ self.indata = {}
367
+ self.parent = parent
368
+ self.combobox1.hide()
369
+ self.label1.hide()
370
+ self.combobox2.hide()
371
+ self.label2.hide()
372
+ self.spinbox.hide()
373
+ self.label3.hide()
374
+
375
+ def run(self):
376
+ """ Run """
377
+ self.show()
378
+ data = self.indata['Vector']
379
+ self.mmc.update_vector(data)
380
+ # for i in data:
381
+ # self.combobox1.addItem(i.dataid)
382
+ # self.combobox2.addItem(i.dataid)
383
+
384
+ # self.label1.setText('Top Profile:')
385
+ # self.label2.setText('Bottom Profile:')
386
+ # self.combobox1.setCurrentIndex(0)
387
+ # self.combobox2.setCurrentIndex(1)
388
+
389
+
390
+ def histogram(x, y=None, xmin=None, xmax=None, bins=10):
391
+ """
392
+ Calculate histogram of a set of data. It is different from a
393
+ conventional histogram in that instead of summing elements of
394
+ specific values, this allows the sum of weights/probabilities on a per
395
+ element basis.
396
+
397
+ Parameters
398
+ ----------
399
+ x : numpy array
400
+ Input data
401
+ y : numpy array
402
+ Input data weights. A value of 1 is default behaviour
403
+ xmin : float
404
+ Lower value for the bins
405
+ xmax : float
406
+ Upper value for the bins
407
+ bins : int
408
+ number of bins
409
+
410
+ Returns
411
+ -------
412
+ hist : numpy array
413
+ The values of the histogram
414
+ bin_edges : numpy array
415
+ bin edges of the histogram
416
+ """
417
+
418
+ radii = np.zeros(bins)
419
+ theta = np.zeros(bins+1)
420
+
421
+ if y is None:
422
+ y = np.ones_like(x)
423
+ if xmin is None:
424
+ xmin = x.min()
425
+ if xmax is None:
426
+ xmax = x.max()
427
+
428
+ x = np.array(x)
429
+ y = np.array(y)
430
+ theta[-1] = xmax
431
+
432
+ xrange = xmax-xmin
433
+ xbin = xrange/bins
434
+ x_2 = x/xbin
435
+ x_2 = x_2.astype(int)
436
+
437
+ for i in range(bins):
438
+ radii[i] = y[x_2 == i].sum()
439
+ theta[i] = i*xbin
440
+
441
+ hist = radii
442
+ bin_edges = theta
443
+ return hist, bin_edges