Skip to content

Commit e1edc76

Browse files
author
aglavic
committed
- Move all plugin imports to plugins __init__
- Improve style dialog - Hysteresis fit function
1 parent 683ff06 commit e1edc76

File tree

7 files changed

+189
-57
lines changed

7 files changed

+189
-57
lines changed

.project

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
</natures>
1717
<filteredResources>
1818
<filter>
19-
<id>1334233498656</id>
19+
<id>1344408557768</id>
2020
<name></name>
2121
<type>10</type>
2222
<matcher>
@@ -25,7 +25,7 @@
2525
</matcher>
2626
</filter>
2727
<filter>
28-
<id>1334233498661</id>
28+
<id>1344408557770</id>
2929
<name></name>
3030
<type>10</type>
3131
<matcher>
@@ -34,13 +34,22 @@
3434
</matcher>
3535
</filter>
3636
<filter>
37-
<id>1334233498663</id>
37+
<id>1344408557771</id>
3838
<name></name>
3939
<type>10</type>
4040
<matcher>
4141
<id>org.eclipse.ui.ide.multiFilter</id>
4242
<arguments>1.0-name-matches-false-false-debug</arguments>
4343
</matcher>
4444
</filter>
45+
<filter>
46+
<id>1344408557773</id>
47+
<name></name>
48+
<type>6</type>
49+
<matcher>
50+
<id>org.eclipse.ui.ide.multiFilter</id>
51+
<arguments>1.0-name-matches-false-false-*~</arguments>
52+
</matcher>
53+
</filter>
4554
</filteredResources>
4655
</projectDescription>

plot_script/fit_data.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
# import gui functions for active config.gui.toolkit
1515
from plot_script.config import gui as gui_config
1616
import parallel
17+
#prepare other processes by importing all importend modules
1718
parallel.add_actions([
1819
'import numpy',
1920
'from mpfit import mpfit',
@@ -2293,6 +2294,51 @@ class FitLangevin(FitFunction):
22932294
)+p[3]
22942295
fit_function_text='Langevin'
22952296

2297+
class FitHysteresis(FitFunction):
2298+
'''
2299+
Fit two Langevin functions with hysteretic offset and exchange bias shift.
2300+
'''
2301+
# define class variables.
2302+
name="Hysteresis"
2303+
parameters=[1.e-7, 0.1, 0., 20.]
2304+
parameter_names=['M_S', 'H_C', 'H_EB', 'w']
2305+
fit_function_text='M_S=[M_S] H_C=[H_C|2] H_{EB}=[H_EB] w=[w|2]'
2306+
2307+
constrains={
2308+
0: {'bounds': [0., None], 'tied': ''},
2309+
1: {'bounds': [0., None], 'tied': ''},
2310+
3: {'bounds': [0., None], 'tied': ''},
2311+
}
2312+
2313+
2314+
def fit_function(self, p, x):
2315+
'''
2316+
Fit two Langevin functions with horizontal offset.
2317+
Use the x change direction to determine hysteresis branches.
2318+
'''
2319+
M_S=p[0]
2320+
H_C=p[1]
2321+
H_EB=p[2]
2322+
w=p[3]
2323+
left_pos=x[1]>x[0]
2324+
# find point where direction changes
2325+
switch_idx=numpy.where(
2326+
(((-1)**left_pos*(x[:-2]-x[1:-1]))>=0)&
2327+
(((-1)**left_pos*(x[1:-1]-x[2:]))<0)
2328+
)[0][0]+1
2329+
x1=x[:switch_idx]
2330+
x2=x[switch_idx:]
2331+
out1=M_S*self.Langevin(x1-H_EB+((-1)**left_pos*H_C), w)
2332+
out2=M_S*self.Langevin(x2-H_EB-((-1)**left_pos*H_C), w)
2333+
return numpy.append(out1, out2)
2334+
2335+
def Langevin(self, H, w):
2336+
wH=w*H
2337+
res=numpy.zeros_like(H)
2338+
pos=wH!=0
2339+
res[pos]=1./numpy.tanh(wH[pos])-1./(wH[pos])
2340+
return res
2341+
22962342

22972343
class FitFerromagnetic(FitFunction):
22982344
'''
@@ -2834,6 +2880,7 @@ class FitSession(FitSessionGUI):
28342880
FitBrillouineB.name: FitBrillouineB,
28352881
FitBrillouineT.name: FitBrillouineT,
28362882
FitLangevin.name: FitLangevin,
2883+
FitHysteresis.name: FitHysteresis,
28372884
FitFerromagnetic.name: FitFerromagnetic,
28382885
FitCuK.name: FitCuK,
28392886
FitPowerlaw.name: FitPowerlaw,

plot_script/gtkgui/dialogs.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2652,13 +2652,15 @@ def _add_item(self, item):
26522652
def add_item(self, button):
26532653
self.list_link.append(self.entry_type())
26542654
self._add_item(self.entry_type())
2655+
self.emit('activate', self, None)
26552656

26562657
def remove_item(self, button):
26572658
buttons=[item[2] for item in self.list_entries]
26582659
idx=buttons.index(button)
26592660
self.list_link.pop(idx)
26602661
line, ignore, ignore=self.list_entries.pop(idx)
26612662
self.remove(line)
2663+
self.emit('activate', self, None)
26622664

26632665
def entry_changed(self, entry):
26642666
entries=[item[1] for item in self.list_entries]

plot_script/gtkgui/main_window.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -579,10 +579,12 @@ def main_quit(self, action=None, store_config=True):
579579
# exit persistent gnuplot instances
580580
persistent_plot_instances=measurement_data_plotting.persistent_plot_instances
581581
for p in persistent_plot_instances:
582-
if p.stdin.is_open():
583-
p.stdin.write('quit\n')
582+
try:
583+
p.stdin.write('\nquit\n')
584584
p.stdin.flush()
585-
p.communicate()
585+
p.communicate()
586+
except:
587+
pass
586588
# save settings to ini file
587589
if store_config:
588590
if not os.path.exists(os.path.expanduser('~')+'/.plotting_gui'):
@@ -609,3 +611,6 @@ def main_quit(self, action=None, store_config=True):
609611
except RuntimeError:
610612
pass
611613

614+
gobject.type_register(ApplicationMainWindow)
615+
gobject.signal_new("plot-drawn", ApplicationMainWindow, gobject.SIGNAL_RUN_FIRST,
616+
gobject.TYPE_NONE, ())

plot_script/gtkgui/main_window_plotting.py

Lines changed: 74 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from plot_script import measurement_data_plotting
1111
from plot_script.config import gnuplot_preferences, user_config
1212
from dialogs import LabelArrowDialog, StyleLine, SimpleEntryDialog, \
13-
PreviewDialog
13+
PreviewDialog, VListEntry
1414
from diverse_classes import PlotProfile
1515

1616
errorbars=False
@@ -357,6 +357,7 @@ def replot(self, echo=True):
357357
# make sure hugeMD objects are removed from memory after plotting
358358
if hasattr(self.active_dataset, 'tmp_export_file'):
359359
self.active_dataset.store_data()
360+
self.emit('plot-drawn')
360361

361362
def open_plot_options_window(self, action):
362363
'''
@@ -616,43 +617,73 @@ def show_last_plot_params(self, action):
616617
param_dialog=gtk.Dialog(title='Last plot parameters:')
617618
param_dialog.set_default_size(600, 600)
618619
# alignment table
619-
table=gtk.Table(1, 2, False)
620+
vbox1=gtk.VBox()
620621
paned=gtk.VPaned()
621622

622623
# Label
623624
label=gtk.Label('Gnuplot input for the last plot:')
624-
table.attach(label, 0, 1, 0, 1, 0, 0, 0, 0);
625+
vbox1.pack_start(label, expand=False)
625626

626627
# plot options
627628
sw=gtk.ScrolledWindow()
628629
# Set the adjustments for horizontal and vertical scroll bars.
629630
# POLICY_AUTOMATIC will automatically decide whether you need
630631
# scrollbars.
631632
sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
632-
text_field=gtk.Label(plot_text)
633+
text_field1=gtk.Label(plot_text)
633634
#text_filed.set_markup(plot_text.replace('<', '[').replace('>', ']'))
634-
sw.add_with_viewport(text_field) # add textbuffer view widget
635-
table.attach(sw, 0, 1, 1, 2, gtk.EXPAND|gtk.FILL, gtk.EXPAND|gtk.FILL, 0, 0)
636-
paned.add(table)
635+
sw.add_with_viewport(text_field1) # add textbuffer view widget
636+
vbox1.add(sw)
637+
paned.add1(vbox1)
637638
# errors of the last plot
638-
if self.last_plot_text!='':
639-
table=gtk.Table(1, 2, False)
640-
# Label
641-
label=gtk.Label('Error during execution:')
642-
table.attach(label, 0, 1, 0, 1, 0, 0, 0, 0);
643-
sw=gtk.ScrolledWindow()
644-
# Set the adjustments for horizontal and vertical scroll bars.
645-
# POLICY_AUTOMATIC will automatically decide whether you need
646-
# scrollbars.
647-
sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
648-
text_field=gtk.Label(self.last_plot_text)
649-
#text_field.set_markup()
650-
sw.add_with_viewport(text_field) # add textbuffer view widget
651-
table.attach(sw, 0, 1, 1, 2, gtk.EXPAND|gtk.FILL, gtk.EXPAND|gtk.FILL, 0, 0)
652-
paned.add(table)
653-
paned.set_position(400)
639+
vbox2=gtk.VBox()
640+
# Label
641+
label=gtk.Label('Error during execution:')
642+
vbox2.pack_start(label, expand=False)
643+
sw=gtk.ScrolledWindow()
644+
# Set the adjustments for horizontal and vertical scroll bars.
645+
# POLICY_AUTOMATIC will automatically decide whether you need
646+
# scrollbars.
647+
sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
648+
text_field2=gtk.Label(self.last_plot_text)
649+
#text_field.set_markup()
650+
sw.add_with_viewport(text_field2) # add textbuffer view widget
651+
vbox2.add(sw)
652+
paned.add2(vbox2)
653+
paned.set_position(400)
654654
param_dialog.vbox.add(paned)
655655
param_dialog.show_all()
656+
if self.last_plot_text=='':
657+
paned.set_position(580)
658+
def update_text(ignore):
659+
# recreate string after replot command
660+
if self.active_multiplot:
661+
itemlist=[item[0] for item in self.multiplot]
662+
if self.active_dataset in itemlist:
663+
new_plot_text=measurement_data_plotting.create_plot_script(
664+
self.active_session,
665+
[item[0] for item in self.multiplot],
666+
self.active_session.active_file_name,
667+
'',
668+
self.multiplot[0][0].short_info,
669+
[item[0].short_info for item in self.multiplot],
670+
errorbars,
671+
self.active_session.TEMP_DIR+'plot_temp.png',
672+
fit_lorentz=False)
673+
else:
674+
new_plot_text=measurement_data_plotting.create_plot_script(
675+
self.active_session,
676+
[self.active_dataset],
677+
self.active_session.active_file_name,
678+
'',
679+
self.active_dataset.short_info,
680+
[ds.short_info for ds in self.active_dataset.plot_together],
681+
errorbars,
682+
output_file=self.active_session.TEMP_DIR+'plot_temp.png',
683+
fit_lorentz=False)
684+
text_field1.set_text(new_plot_text)
685+
text_field2.set_text(self.last_plot_text)
686+
self.connect('plot-drawn', update_text)
656687
# connect dialog to main window
657688
self.open_windows.append(param_dialog)
658689
param_dialog.connect("destroy", lambda*w: self.open_windows.remove(param_dialog))
@@ -750,6 +781,7 @@ def change_plot_style(self, action):
750781
Open a Dialog to chang the style of the current plot.
751782
'''
752783
dialog=gtk.Dialog(title='Plot style settings...', parent=self)
784+
dialog.set_default_size(600, 300)
753785
nb=gtk.Notebook()
754786
nb.show()
755787
dialog.vbox.add(nb)
@@ -768,11 +800,11 @@ def change_plot_style(self, action):
768800
tentry.show()
769801
title.add(entry)
770802
title.add(tentry)
771-
dialog.vbox.add(title)
803+
dialog.vbox.pack_start(title, expand=False)
772804
tentry.connect('activate', self.change_plot_shortinfo, dataset)
773805
line=StyleLine(dataset.plot_options, self.replot)
774806
line.show()
775-
main_items.add(line)
807+
main_items.pack_start(line, expand=False)
776808
i+=1
777809
else:
778810
datasets=self.active_dataset.plot_together
@@ -787,10 +819,10 @@ def change_plot_style(self, action):
787819
tentry.connect('activate', self.change_plot_shortinfo, dataset)
788820
title.add(entry)
789821
title.add(tentry)
790-
main_items.add(title)
822+
main_items.pack_start(title, expand=False)
791823
line=StyleLine(dataset.plot_options, self.replot)
792824
line.show()
793-
main_items.add(line)
825+
main_items.pack_start(line, expand=False)
794826
sw=gtk.ScrolledWindow()
795827
sw.add_with_viewport(main_items)
796828
sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
@@ -799,7 +831,22 @@ def change_plot_style(self, action):
799831
# Create entries for the advanced options of the PlotOptions class
800832
advanced_items=gtk.VBox()
801833
#
834+
pre_entry=VListEntry(self.active_dataset.plot_options.free_input,
835+
title='Custom commands before script')
836+
pre_entry.show()
837+
advanced_items.pack_start(pre_entry, expand=False)
838+
advanced_items.show_all()
839+
pre_entry.connect('activate', lambda *ignore: self.replot())
840+
post_entry=VListEntry(self.active_dataset.plot_options.free_input_after,
841+
title='Custom commands after settings')
842+
post_entry.show()
843+
advanced_items.pack_start(post_entry, expand=False)
844+
button=gtk.Button('Show gnuplot script')
845+
button.connect('clicked', self.show_last_plot_params)
846+
advanced_items.pack_end(button, expand=False)
802847
advanced_items.show_all()
848+
post_entry.connect('activate', lambda *ignore: self.replot())
849+
#
803850
nb.append_page(advanced_items, gtk.Label('Advanced Gnuplot Settings'))
804851
dialog.show()
805852
self.open_windows.append(dialog)

plot_script/plugins/__init__.py

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,59 @@
11
# -*- coding: utf-8 -*-
2-
32
'''
4-
Plot.py global plugins package. Scans the plugins folder for python files and imports them.
3+
Plot.py global plugins package. Scans the global and user plugins folder
4+
for python files and imports them.
5+
6+
To import all plugin modules directly use:
7+
from plot_script.plugins import * # import to namespace
8+
or
9+
from plot_script.plugins import all_plugins # import list of modules
510
'''
611

712
import sys
813
import os
14+
915
# Add this folder to python path
1016
global_plugin_path=os.path.abspath(os.path.split(__file__)[0])
1117
if not global_plugin_path in sys.path:
1218
sys.path.append(global_plugin_path)
1319

20+
__all__=[]
21+
22+
# plugins from the program folder
1423
global_plugins=[]
1524
plugin_sources=os.listdir(global_plugin_path)
1625
plugin_sources=filter(lambda file_name: file_name.endswith('.py'), plugin_sources)
1726
for plugin_source in plugin_sources:
18-
plugin=__import__(plugin_source[:-3])
19-
global_plugins.append(plugin)
27+
if plugin_source.startswith('_'):
28+
continue
29+
try:
30+
plugin=__import__('plot_script.plugins.'+plugin_source[:-3], fromlist=[plugin_source[:-3]])
31+
except ImportError, error:
32+
print "Error importing plugin %s, skipped. Error message: %s"%(plugin_source, error)
33+
else:
34+
global_plugins.append(plugin)
35+
exec '%s=plugin'%plugin_source[:-3]
36+
__all__.append(plugin_source[:-3])
37+
38+
# plugins from the user folder
39+
user_plugins=[]
40+
user_folder=os.path.join(os.path.expanduser('~'), '.plotting_gui')
41+
if os.path.exists(user_folder) and os.path.exists(os.path.join(user_folder, 'plugins')):
42+
if not os.path.join(user_folder, 'plugins') in sys.path:
43+
sys.path.append(os.path.join(user_folder, 'plugins'))
44+
plugin_sources=os.listdir(os.path.join(user_folder, 'plugins'))
45+
plugin_sources=filter(lambda file_: file_.endswith('.py'), plugin_sources)
46+
for plugin_source in plugin_sources:
47+
if plugin_source.startswith('_'):
48+
continue
49+
try:
50+
plugin=__import__(plugin_source[:-3])
51+
except ImportError, error:
52+
print "Error importing plugin %s, skipped. Error message: %s"%(plugin_source, error)
53+
else:
54+
user_plugins.append(plugin)
55+
exec '%s=plugin'%plugin_source[:-3]
56+
__all__.append(plugin_source[:-3])
57+
58+
59+
all_plugins=global_plugins+user_plugins

0 commit comments

Comments
 (0)