1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 import VisionEgg
18 __version__ = VisionEgg.release_name
19 __cvs__ = '$Revision: 1455 $'.split()[1]
20 __date__ = ' '.join('$Date: 2008-06-07 08:42:14 -0700 (Sat, 07 Jun 2008) $'.split()[1:3])
21 __author__ = 'Andrew Straw <astraw@users.sourceforge.net>'
22
23 import sys, socket, re, time, string, types, os
24 import parser, symbol, token, compiler
25 import pickle, random, math, threading
26 import Tkinter, tkMessageBox, tkSimpleDialog, tkFileDialog
27 import StringIO
28 import Pyro
29 import numpy
30
31 import VisionEgg
32 import VisionEgg.PyroClient
33 import VisionEgg.PyroApps.ScreenPositionGUI
34 import VisionEgg.GUI
35 import VisionEgg.ParameterTypes as ve_types
36
37
38 import VisionEgg.PyroApps.TargetGUI
39 import VisionEgg.PyroApps.MouseTargetGUI
40 import VisionEgg.PyroApps.FlatGratingGUI
41 import VisionEgg.PyroApps.SphereGratingGUI
42 import VisionEgg.PyroApps.SpinningDrumGUI
43 import VisionEgg.PyroApps.GridGUI
44 import VisionEgg.PyroApps.ColorCalGUI
45
46 import VisionEgg.PyroApps.DropinGUI
47 import VisionEgg.PyroApps.AST_ext as AST_ext
48 import VisionEgg.PyroApps.VarTypes as VarTypes
49
50 client_list = []
51 client_list.extend( VisionEgg.PyroApps.TargetGUI.get_control_list() )
52 client_list.extend( VisionEgg.PyroApps.MouseTargetGUI.get_control_list() )
53 client_list.extend( VisionEgg.PyroApps.FlatGratingGUI.get_control_list() )
54 client_list.extend( VisionEgg.PyroApps.SphereGratingGUI.get_control_list() )
55 client_list.extend( VisionEgg.PyroApps.SpinningDrumGUI.get_control_list() )
56 client_list.extend( VisionEgg.PyroApps.GridGUI.get_control_list() )
57 client_list.extend( VisionEgg.PyroApps.ColorCalGUI.get_control_list() )
58 client_list.extend( VisionEgg.PyroApps.DropinGUI.get_control_list() )
59
61 """Base class to encapsulate objects, provides useful methods when used in GUI"""
63 raise RuntimeError("Abstract base class!")
65 return "**** this is a generic str_30 ****"
68 header = "unknown parameters"
69
488
489
490 -class Loop(VisionEgg.ClassWithParameters):
491 parameters_and_defaults = {'variable':('<repeat>',
492 ve_types.String),
493 'sequence':([1, 1, 1],
494 ve_types.Sequence(ve_types.Real)),
495 'rest_duration_sec':(1.0,
496 ve_types.Real)}
497 __slots__ = (
498 'num_done',
499 )
500
501
506 return self.num_done >= len(self.parameters.sequence)
508 return self.parameters.sequence[self.num_done]
513
515 """Container for Loop class"""
516 contained_class = Loop
517 header = " variable rest N values"
519 self.contained = contained
521 p = self.contained.parameters
522 seq_str = ""
523 for val in p.sequence:
524 seq_str += str(val) + " "
525 name_str = p.variable
526 if len(name_str) > 15:
527 name_str = name_str[:15]
528 return "% 15s % 4s % 4d % 4s"%(name_str, str(p.rest_duration_sec), len(p.sequence), seq_str)
529
532
533 if kw.has_key('orig_values'):
534 self.orig_values = kw['orig_values']
535 del kw['orig_values']
536 else:
537 self.orig_values = None
538 return tkSimpleDialog.Dialog.__init__(self, *args, **kw )
539
540 - def body(self,master):
541 Tkinter.Label(master,
542 text="Add sequence of automatic variable values",
543 font=("Helvetica",12,"bold"),).grid(row=0,column=0,columnspan=2)
544
545 var_frame = Tkinter.Frame(master,
546 relief=Tkinter.GROOVE,
547 borderwidth=2)
548 var_frame.grid(row=1,column=0)
549
550 sequence_frame = Tkinter.Frame(master)
551 sequence_frame.grid(row=1,column=1)
552
553 rest_dur_frame = Tkinter.Frame(master)
554 rest_dur_frame.grid(row=2,column=0,columnspan=2)
555
556
557 global loopable_variables
558 num_cols = int(math.ceil(len(loopable_variables)/10.0))
559
560 var_frame_row = 0
561 Tkinter.Label(var_frame,
562 text="Select a variable",
563 font=("Helvetica",12,"bold"),).grid(row=var_frame_row,
564 column=0,
565 columnspan=num_cols)
566
567 self.var_name = Tkinter.StringVar()
568 self.var_name.set("<repeat>")
569 var_names = loopable_variables[:]
570 var_names.sort()
571
572 var_frame_row += 1
573 Tkinter.Radiobutton( var_frame,
574 text="Repeat (Average)",
575 variable=self.var_name,
576 value="<repeat>",
577 anchor=Tkinter.W).grid(row=var_frame_row,
578 column=0,
579 sticky="w")
580 var_frame_row += 1
581 for var_name in var_names:
582 use_row = var_frame_row%10+1
583 Tkinter.Radiobutton( var_frame,
584 text=var_name,
585 variable=self.var_name,
586 value=var_name,
587 anchor=Tkinter.W).grid(row=use_row,
588 column=int(math.floor(var_frame_row/10.)),
589 sticky="w")
590 var_frame_row += 1
591
592
593 seq_row = 0
594 Tkinter.Label(sequence_frame,
595 text="Sequence values",
596 font=("Helvetica",12,"bold"),).grid(row=seq_row,column=0,columnspan=2)
597
598 seq_row += 1
599 self.sequence_type = Tkinter.StringVar()
600 self.sequence_type.set("manual")
601
602 Tkinter.Radiobutton( sequence_frame,
603 text="Manual:",
604 variable=self.sequence_type,
605 value="manual",
606 anchor=Tkinter.W).grid(row=seq_row,column=0,sticky="w")
607
608 self.sequence_manual_string = Tkinter.StringVar()
609 self.sequence_manual_string.set("[1,2,3]")
610 Tkinter.Entry(sequence_frame,
611 textvariable=self.sequence_manual_string).grid(row=seq_row,column=1)
612
613 seq_row += 1
614 Tkinter.Radiobutton( sequence_frame,
615 text="Linear:",
616 variable=self.sequence_type,
617 value="linear",
618 anchor=Tkinter.W).grid(row=seq_row,column=0,sticky="w")
619
620 self.lin_start_tk = Tkinter.DoubleVar()
621 self.lin_start_tk.set(1.0)
622 self.lin_stop_tk = Tkinter.DoubleVar()
623 self.lin_stop_tk.set(100.0)
624 self.lin_n_tk = Tkinter.IntVar()
625 self.lin_n_tk.set(3)
626
627 lin_frame = Tkinter.Frame( sequence_frame)
628 lin_frame.grid(row=seq_row,column=1)
629 Tkinter.Label(lin_frame,text="start:").grid(row=0,column=0)
630 Tkinter.Entry(lin_frame,textvariable=self.lin_start_tk,width=6).grid(row=0,column=1)
631 Tkinter.Label(lin_frame,text=" stop:").grid(row=0,column=2)
632 Tkinter.Entry(lin_frame,textvariable=self.lin_stop_tk,width=6).grid(row=0,column=3)
633 Tkinter.Label(lin_frame,text=" N:").grid(row=0,column=4)
634 Tkinter.Entry(lin_frame,textvariable=self.lin_n_tk,width=6).grid(row=0,column=5)
635
636 seq_row += 1
637 Tkinter.Radiobutton( sequence_frame,
638 text="Log:",
639 variable=self.sequence_type,
640 value="log",
641 anchor=Tkinter.W).grid(row=seq_row,column=0,sticky="w")
642
643 self.log_start_tk = Tkinter.DoubleVar()
644 self.log_start_tk.set(-1.0)
645 self.log_stop_tk = Tkinter.DoubleVar()
646 self.log_stop_tk.set(2.0)
647 self.log_n_tk = Tkinter.IntVar()
648 self.log_n_tk.set(5)
649
650 log_frame = Tkinter.Frame( sequence_frame)
651 log_frame.grid(row=seq_row,column=1)
652 Tkinter.Label(log_frame,text="start: 10^").grid(row=0,column=0)
653 Tkinter.Entry(log_frame,textvariable=self.log_start_tk,width=6).grid(row=0,column=1)
654 Tkinter.Label(log_frame,text=" stop: 10^").grid(row=0,column=2)
655 Tkinter.Entry(log_frame,textvariable=self.log_stop_tk,width=6).grid(row=0,column=3)
656 Tkinter.Label(log_frame,text=" N:").grid(row=0,column=4)
657 Tkinter.Entry(log_frame,textvariable=self.log_n_tk,width=6).grid(row=0,column=5)
658
659 seq_row += 1
660 Tkinter.Radiobutton( sequence_frame,
661 text="Log:",
662 variable=self.sequence_type,
663 value="logb",
664 anchor=Tkinter.W).grid(row=seq_row,column=0,sticky="w")
665
666 self.logb_start_tk = Tkinter.DoubleVar()
667 self.logb_start_tk.set(0.1)
668 self.logb_stop_tk = Tkinter.DoubleVar()
669 self.logb_stop_tk.set(100.0)
670 self.logb_n_tk = Tkinter.IntVar()
671 self.logb_n_tk.set(5)
672
673 logb_frame = Tkinter.Frame( sequence_frame)
674 logb_frame.grid(row=seq_row,column=1)
675 Tkinter.Label(logb_frame,text="start:").grid(row=0,column=0)
676 Tkinter.Entry(logb_frame,textvariable=self.logb_start_tk,width=6).grid(row=0,column=1)
677 Tkinter.Label(logb_frame,text=" stop:").grid(row=0,column=2)
678 Tkinter.Entry(logb_frame,textvariable=self.logb_stop_tk,width=6).grid(row=0,column=3)
679 Tkinter.Label(logb_frame,text=" N:").grid(row=0,column=4)
680 Tkinter.Entry(logb_frame,textvariable=self.logb_n_tk,width=6).grid(row=0,column=5)
681
682
683 Tkinter.Label(rest_dur_frame,
684 text="Other sequence parameters",
685 font=("Helvetica",12,"bold"),).grid(row=0,column=0,columnspan=2)
686
687 Tkinter.Label(rest_dur_frame,
688 text="Interval duration (seconds)").grid(row=1,column=0)
689 self.rest_dur = Tkinter.DoubleVar()
690 self.rest_dur.set(0.5)
691 Tkinter.Entry(rest_dur_frame,
692 textvariable=self.rest_dur,
693 width=10).grid(row=1,column=1)
694
695 self.shuffle_tk_var = Tkinter.BooleanVar()
696 self.shuffle_tk_var.set(0)
697 Tkinter.Checkbutton( rest_dur_frame,
698 text="Shuffle sequence order",
699 variable=self.shuffle_tk_var).grid(row=2,column=0,columnspan=2)
700
701 if self.orig_values is not None:
702 self.var_name.set( self.orig_values.parameters.variable )
703
704 self.sequence_manual_string.set( str(self.orig_values.parameters.sequence) )
705
706 self.rest_dur.set( self.orig_values.parameters.rest_duration_sec )
707
708
710 if self.sequence_type.get() == "manual":
711 try:
712 seq = eval(self.sequence_manual_string.get())
713 except Exception, x:
714 tkMessageBox.showwarning("Invalid sequence parameters",
715 "Manual sequence entry: %s"%(str(x),),
716 parent=self)
717 return 0
718 if type(seq) != types.ListType:
719 tkMessageBox.showwarning("Invalid sequence parameters",
720 "Manual sequence entry: Not a list",
721 parent=self)
722 return 0
723 elif self.sequence_type.get() == "linear":
724 start = self.lin_start_tk.get()
725 stop = self.lin_stop_tk.get()
726 n = self.lin_n_tk.get()
727 if n < 2:
728 tkMessageBox.showwarning("Invalid sequence parameters",
729 "Must have n >= 2.",
730 parent=self)
731 return 0
732
733 incr = (stop-start)/float(n-1)
734 seq = range(n)
735 for i in range(n):
736 seq[i] = i*incr + start
737 elif self.sequence_type.get() == "log":
738 start = self.log_start_tk.get()
739 stop = self.log_stop_tk.get()
740 n = self.log_n_tk.get()
741 if n < 2:
742 tkMessageBox.showwarning("Invalid sequence parameters",
743 "Must have n >= 2.",
744 parent=self)
745 return 0
746
747 incr = (stop-start)/float(n-1)
748 seq = range(n)
749 for i in range(n):
750 seq[i] = 10.0**( i*incr + start )
751 elif self.sequence_type.get() == "logb":
752 start = self.logb_start_tk.get()
753 stop = self.logb_stop_tk.get()
754 start = math.log10(start)
755 stop = math.log10(stop)
756 n = self.logb_n_tk.get()
757 if n < 2:
758 tkMessageBox.showwarning("Invalid sequence parameters",
759 "Must have n >= 2.",
760 parent=self)
761 return 0
762 incr = (stop-start)/float(n-1)
763 seq = range(n)
764 for i in range(n):
765 seq[i] = 10.0**( i*incr + start )
766 else:
767 tkMessageBox.showwarning("Invalid sequence parameters",
768 "Invalid sequence type.",
769 parent=self)
770 return 0
771 rest_dur_sec = self.rest_dur.get()
772
773 if self.shuffle_tk_var.get():
774 random.shuffle(seq)
775
776 self.result = Loop(variable=self.var_name.get(),
777 sequence=seq,
778 rest_duration_sec=rest_dur_sec)
779 return 1
780
782
783 self.var_name = None
784 self.sequence_type = None
785 self.sequence_manual_string = None
786 self.rest_dur = None
787
788 tkSimpleDialog.Dialog.destroy(self)
789
791 class ConnectWindow(Tkinter.Frame):
792 def __init__(self,master=None,hostname="",port=7766,**kw):
793
794 VisionEgg.config._Tkinter_used = True
795
796 Tkinter.Frame.__init__(self,master, **kw)
797 self.winfo_toplevel().title("EPhysGUI Connect - Vision Egg")
798 current_row = 0
799 Tkinter.Message(self,\
800 text='Welcome to the "EPhys GUI" of the Vision Egg!\n\n'+\
801 'Please enter the hostname '+\
802 'and port number '+\
803 'of the computer on which you have the '+\
804 '"EPhys server" running.').grid(row=current_row,column=0,columnspan=2)
805 hostname = 'localhost'
806
807 self.hostname_tk = Tkinter.StringVar()
808 self.hostname_tk.set(hostname)
809 current_row += 1
810 Tkinter.Label(self,text="Hostname:").grid(row=current_row, column=0)
811 Tkinter.Entry(self,textvariable=self.hostname_tk).grid(row=current_row, column=1)
812
813 self.port_tk = Tkinter.IntVar()
814 self.port_tk.set(port)
815 current_row += 1
816 Tkinter.Label(self,text="Port:").grid(row=current_row, column=0)
817 Tkinter.Entry(self,textvariable=self.port_tk).grid(row=current_row, column=1)
818
819 current_row += 1
820 bf = Tkinter.Frame(self)
821 bf.grid(row=current_row,column=0,columnspan=2)
822 ok=Tkinter.Button(bf,text="OK",command=self.ok)
823 ok.grid(row=0,column=0)
824 ok.focus_force()
825 ok.bind('<Return>',self.ok)
826 Tkinter.Button(bf,text="Cancel",command=self.quit).grid(row=0,column=1)
827 self.result = None
828
829 def ok(self,dummy_arg=None):
830 self.result = (self.hostname_tk.get(),self.port_tk.get())
831 self.destroy()
832 self.quit()
833
834 connect_win = ConnectWindow(hostname=hostname,port=port)
835 connect_win.pack()
836 connect_win.mainloop()
837 return connect_win.result
838
840 - def __init__(self,
841 master=None,
842 ephys_server=None,**kw):
843 Tkinter.Frame.__init__(self,master,**kw)
844 self.winfo_toplevel().title("Gamma - Vision Egg")
845 self.ephys_server = ephys_server
846
847 self.columnconfigure(0,weight=1)
848
849 row = 0
850 Tkinter.Label(self,
851 font=("Helvetica",12,"bold"),
852 text="Load Gamma Table").grid(row=row)
853
854 row += 1
855 Tkinter.Button(self,
856 text="Set from .ve_gamma file...",
857 command=self.set_from_file).grid(row=row,sticky="w")
858
859 row += 1
860 Tkinter.Button(self,
861 text="Set to monitor default (linear gamma table)",
862 command=self.set_monitor_default).grid(row=row,sticky="w")
863
864 row += 1
865 invert_frame = Tkinter.Frame(self)
866 invert_frame.grid(row=row,sticky="we")
867
868 Tkinter.Button(invert_frame,
869 text="Linearize luminance for gammas",
870 command=self.linearize).grid(row=0,column=0)
871
872 Tkinter.Label(invert_frame,
873 text="Red:").grid(row=0,column=1)
874
875 self.red_gamma = Tkinter.DoubleVar()
876 self.red_gamma.set(2.2)
877
878 Tkinter.Entry(invert_frame,
879 textvariable=self.red_gamma,
880 width=5).grid(row=0,column=2)
881
882 Tkinter.Label(invert_frame,
883 text="Green:").grid(row=0,column=3)
884
885 self.green_gamma = Tkinter.DoubleVar()
886 self.green_gamma.set(2.2)
887
888 Tkinter.Entry(invert_frame,
889 textvariable=self.green_gamma,
890 width=5).grid(row=0,column=4)
891
892 Tkinter.Label(invert_frame,
893 text="Blue:").grid(row=0,column=5)
894
895 self.blue_gamma = Tkinter.DoubleVar()
896 self.blue_gamma.set(2.2)
897
898 Tkinter.Entry(invert_frame,
899 textvariable=self.blue_gamma,
900 width=5).grid(row=0,column=6)
901
902 row += 1
903 self.success_label = Tkinter.Label(self)
904 self.success_label.grid(row=row)
905
907
908
909
910 c = 1.0
911 inc = 1.0/255
912 target_luminances = numpy.arange(0.0,1.0+inc,inc)
913 output_ramp = numpy.zeros(target_luminances.shape,dtype=numpy.int32)
914 for i in range(len(target_luminances)):
915 L = target_luminances[i]
916 if L == 0.0:
917 v_88fp = 0
918 else:
919 v = math.exp( (math.log(L) - math.log(c)) /gamma)
920 v_88fp = int(round((v*255) * 256))
921 output_ramp[i] = v_88fp
922 return list(output_ramp)
923
925 self.success_label.configure(text="Setting...")
926 try:
927 red = self.get_corrected_gamma_table(self.red_gamma.get())
928 green = self.get_corrected_gamma_table(self.green_gamma.get())
929 blue = self.get_corrected_gamma_table(self.blue_gamma.get())
930 except:
931 self.success_label.configure(text="Calculation error")
932 raise
933 try:
934 if self.ephys_server.set_gamma_ramp(red,green,blue):
935 self.success_label.configure(text="Success")
936 else:
937 self.success_label.configure(text="Failed: Invalid gamma values?")
938 except Exception,x:
939 self.success_label.configure(text="Failed: %s: %s"%(x.__class__,str(x)))
940 raise
941
943 self.success_label.configure(text="Setting...")
944 try:
945 red = self.get_corrected_gamma_table(1.0)
946 except:
947 self.success_label.configure(text="Calculation error")
948 raise
949 green = red
950 blue = red
951 try:
952 if self.ephys_server.set_gamma_ramp(red,green,blue):
953 self.success_label.configure(text="Success")
954 else:
955 self.success_label.configure(text="Failed: Invalid gamma values?")
956 except Exception,x:
957 self.success_label.configure(text="Failed: %s: %s"%(x.__class__,str(x)))
958 raise
959
961 self.success_label.configure(text="Setting...")
962 filename = tkFileDialog.askopenfilename(
963 parent=self,
964 defaultextension=".ve_gamma",
965 filetypes=[('Configuration file','*.ve_gamma')],
966 initialdir=VisionEgg.config.VISIONEGG_USER_DIR)
967 if not filename:
968 self.success_label.configure(text="No file given")
969 return
970 fd = open(filename,"r")
971 gamma_values = []
972 for line in fd.readlines():
973 line = line.strip()
974 if line.startswith("#"):
975 continue
976 try:
977 gamma_values.append( map(int, line.split() ) )
978 except Exception, x:
979 self.success_label.configure(text="File error")
980 raise
981 if len(gamma_values[-1]) != 3:
982 self.success_label.configure(text="File error")
983 raise RuntimeError("expected 3 values per gamma entry")
984 if len(gamma_values) != 256:
985 self.success_label.configure(text="File error")
986 raise RuntimeError("expected 256 gamma entries")
987 red, green, blue = zip(*gamma_values)
988 try:
989 if self.ephys_server.set_gamma_ramp(red,green,blue):
990 self.success_label.configure(text="Success")
991 else:
992 self.success_label.configure(text="Failed: Invalid gamma values?")
993 except Exception,x:
994 self.success_label.configure(text="Failed: %s: %s"%(x.__class__,str(x)))
995 raise
996
998 - def __init__(self,master=None,ephys_server=None,**cnf):
999 Tkinter.Toplevel.__init__(self,master,**cnf)
1000 if ephys_server is None:
1001 raise ValueError("Must specify ephys_server")
1002 self.ephys_server = ephys_server
1003
1004 self.columnconfigure(1,weight=1)
1005
1006 row = 0
1007 Tkinter.Label(self,text="Frames per second").grid(row=row,column=0)
1008 self.fps_var = Tkinter.DoubleVar()
1009 self.fps_var.set(12.0)
1010 Tkinter.Entry(self,textvariable=self.fps_var).grid(row=row,column=1,sticky="we")
1011 row += 1
1012 Tkinter.Label(self,text="Filename base").grid(row=row,column=0)
1013 self.filename_base = Tkinter.StringVar()
1014 self.filename_base.set("im")
1015 Tkinter.Entry(self,textvariable=self.filename_base).grid(row=row,column=1,sticky="we")
1016 row += 1
1017 Tkinter.Label(self,text="Filename suffix").grid(row=row,column=0)
1018 self.filename_suffix = Tkinter.StringVar()
1019 self.filename_suffix.set(".tif")
1020 Tkinter.Entry(self,textvariable=self.filename_suffix).grid(row=row,column=1,sticky="we")
1021 row += 1
1022 Tkinter.Label(self,text="Save directory on server").grid(row=row,column=0)
1023 self.server_save_dir = Tkinter.StringVar()
1024 server_dir = self.ephys_server.get_cwd()
1025 self.server_save_dir.set(server_dir)
1026 Tkinter.Entry(self,textvariable=self.server_save_dir).grid(row=row,column=1,sticky="we")
1027 row += 1
1028 Tkinter.Button(self,text="Save movie",command=self.do_it).grid(row=row,column=0,columnspan=2)
1029 self.focus_set()
1030 self.grab_set()
1032 fps = self.fps_var.get()
1033 filename_base = self.filename_base.get()
1034 filename_suffix = self.filename_suffix.get()
1035 server_save_dir = self.server_save_dir.get()
1036 self.ephys_server.save_image_sequence(fps=fps,
1037 filename_base=filename_base,
1038 filename_suffix=filename_suffix,
1039 save_dir=server_save_dir)
1040 self.destroy()
1041
1043 - def __init__(self,
1044 master=None,
1045 client_list=None,
1046 server_hostname='',
1047 server_port=7766,
1048 **cnf):
1049
1050 if hasattr(VisionEgg, '_exception_hook_keeper'):
1051
1052 self._orig_report_callback_exception = Tkinter.Tk.report_callback_exception
1053 self._tk = Tkinter.Tk
1054
1055 Tkinter.Tk.report_callback_exception = VisionEgg._exception_hook_keeper.handle_exception
1056
1057
1058 VisionEgg.config._Tkinter_used = True
1059
1060
1061 Tkinter.Frame.__init__(self,master, **cnf)
1062 self.winfo_toplevel().title("EPhysGUI - Vision Egg")
1063
1064 self.client_list = client_list
1065
1066 self.server_hostname = server_hostname
1067 self.server_port = server_port
1068
1069 self.pyro_client = VisionEgg.PyroClient.PyroClient(self.server_hostname,self.server_port)
1070 self.ephys_server = self.pyro_client.get("ephys_server")
1071 self.ephys_server.first_connection()
1072
1073 self.stim_onset_cal_tk_var = Tkinter.BooleanVar()
1074 self.stim_onset_cal_tk_var.set(0)
1075
1076 self.autosave_dir = Tkinter.StringVar()
1077 self.autosave_dir.set( os.path.abspath(os.curdir) )
1078
1079 self.autosave_basename = Tkinter.StringVar()
1080
1081
1082 self.bar = Tkinter.Menu(tearoff=0)
1083 top = self.winfo_toplevel()
1084 top.configure(menu=self.bar)
1085
1086 self.bar.file_menu = Tkinter.Menu(self.bar, name="file_menu")
1087 self.bar.add_cascade(label="File",menu=self.bar.file_menu)
1088
1089 self.bar.file_menu.add_command(label='Save image sequence...', command=self.save_image_sequence)
1090 self.bar.file_menu.add_command(label='Save configuration file...', command=self.save_config)
1091 self.bar.file_menu.add_command(label='Load configuration file...', command=self.load_config)
1092 self.bar.file_menu.add_command(label='Load auto-saved .py parameter file...', command=self.load_params)
1093 self.bar.file_menu.add_separator()
1094 self.bar.file_menu.add_command(label='Load Vision Egg script...', command=self.load_demoscript)
1095 self.bar.file_menu.add_separator()
1096
1097 self.quit_server_too = Tkinter.BooleanVar()
1098 self.quit_server_too.set(1)
1099 self.bar.file_menu.add_checkbutton(label='Quit server too',
1100 variable=self.quit_server_too)
1101 self.bar.file_menu.add_command(label='Quit',
1102 command=self.quit,
1103 )
1104
1105 stimkey = self.ephys_server.get_stimkey()
1106 self.stimulus_tk_var = Tkinter.StringVar()
1107 self.stimulus_tk_var.set( stimkey )
1108
1109 self.bar.stimuli_menu = Tkinter.Menu(self.bar, name="stimuli_menu")
1110 self.bar.add_cascade(label="Stimuli",menu=self.bar.stimuli_menu)
1111 for maybe_stimkey, maybe_control_frame, maybe_title in self.client_list:
1112 if maybe_title != "Vision Egg Script":
1113 self.bar.stimuli_menu.add_radiobutton(label=maybe_title,
1114 command=self.change_stimulus,
1115 variable=self.stimulus_tk_var,
1116 value=maybe_stimkey)
1117
1118 self.bar.calibration_menu = Tkinter.Menu(self.bar, name="calibration_menu")
1119 self.bar.add_cascade(label="Configure/Calibrate",
1120 menu=self.bar.calibration_menu)
1121
1122 self.bar.calibration_menu.add_command(label='3D Perspective...', command=self.launch_screen_pos)
1123 self.bar.calibration_menu.add_command(label='Stimulus onset timing...', command=self.launch_stim_onset_cal)
1124 self.bar.calibration_menu.add_command(label='Load gamma table...', command=self.launch_gamma_panel)
1125 self.notify_on_dropped_frames = Tkinter.BooleanVar()
1126 self.notify_on_dropped_frames.set(1)
1127 self.bar.calibration_menu.add_checkbutton(label='Warn on frame skip',
1128 variable=self.notify_on_dropped_frames)
1129
1130 self.override_t_abs_sec = Tkinter.StringVar()
1131 self.override_t_abs_sec.set("0.0")
1132
1133 self.override_t_abs_on = Tkinter.BooleanVar()
1134 self.override_t_abs_on.set(0)
1135 self.bar.calibration_menu.add_checkbutton(label='Override server absolute time (CAUTION)',
1136 variable=self.override_t_abs_on)
1137
1138 row = 0
1139
1140
1141 self.stim_frame_cnf = {'row':row,
1142 'column':0,
1143 'columnspan':2,
1144 'sticky':'nwes'}
1145
1146 row += 1
1147 Tkinter.Label(self,
1148 text="Sequence information",
1149 font=("Helvetica",12,"bold")).grid(row=row,column=0)
1150 row += 1
1151
1152 self.loop_frame_cnf = {'row':row,
1153 'column':0,
1154 'sticky':'nwes'}
1155
1156 row -= 1
1157 Tkinter.Label(self,
1158 text="Parameter Save Options",
1159 font=("Helvetica",12,"bold")).grid(row=row,column=1)
1160 row += 1
1161 self.auto_save_frame = Tkinter.Frame(self)
1162 asf = self.auto_save_frame
1163 asf.grid(row=row,column=1,sticky="nwes")
1164 asf.columnconfigure(1,weight=1)
1165
1166 asf.grid_row = 0
1167 self.autosave = Tkinter.BooleanVar()
1168 self.autosave.set(1)
1169 self.auto_save_button = Tkinter.Checkbutton(asf,
1170 text="Auto save trial parameters",
1171 variable=self.autosave)
1172 self.auto_save_button.grid(row=asf.grid_row,column=0,columnspan=2)
1173
1174 self.param_file_type_tk_var = Tkinter.StringVar()
1175 self.param_file_type_tk_var.set("Python format")
1176 filetype_bar = Tkinter.Menubutton(asf,
1177 textvariable=self.param_file_type_tk_var,
1178 relief=Tkinter.RAISED)
1179 filetype_bar.grid(row=asf.grid_row,column=2)
1180 filetype_bar.menu = Tkinter.Menu(filetype_bar,tearoff=0)
1181 filetype_bar.menu.add_radiobutton(label="Python format",
1182 value="Python format",
1183 variable=self.param_file_type_tk_var)
1184 filetype_bar.menu.add_radiobutton(label="Matlab format",
1185 value="Matlab format",
1186 variable=self.param_file_type_tk_var)
1187 filetype_bar['menu'] = filetype_bar.menu
1188
1189 asf.grid_row += 1
1190 Tkinter.Label(asf,
1191 text="Parameter file directory:").grid(row=asf.grid_row,column=0,sticky="e")
1192 Tkinter.Entry(asf,
1193 textvariable=self.autosave_dir).grid(row=asf.grid_row,column=1,sticky="we")
1194 Tkinter.Button(asf,
1195 text="Set...",command=self.set_autosave_dir).grid(row=asf.grid_row,column=2)
1196 asf.grid_row += 1
1197 Tkinter.Label(asf,
1198 text="Parameter file basename:").grid(row=asf.grid_row,column=0,sticky="e")
1199 Tkinter.Entry(asf,
1200 textvariable=self.autosave_basename).grid(row=asf.grid_row,column=1,sticky="we")
1201 Tkinter.Button(asf,
1202 text="Reset",command=self.reset_autosave_basename).grid(row=asf.grid_row,column=2)
1203
1204 row += 1
1205 Tkinter.Button(self, text='Do single trial', command=self.do_single_trial).grid(row=row,column=0)
1206 Tkinter.Button(self, text='Do sequence', command=self.do_loops).grid(row=row,column=1)
1207
1208 row += 1
1209 self.progress = VisionEgg.GUI.ProgressBar(self,
1210 width=300,
1211 relief="sunken",
1212 doLabel=0,
1213 labelFormat="%s")
1214 self.progress.labelText = "Starting..."
1215 self.progress.updateProgress(0)
1216 self.progress.grid(row=row,column=0,columnspan=2)
1217
1218
1219 for i in range(2):
1220 self.columnconfigure(i,weight=1)
1221 for i in range(row+1):
1222 self.rowconfigure(i,weight=1)
1223
1224 self.switch_to_stimkey( stimkey )
1225
1226 self.config_dir = None
1227 self.demoscript_filename = None
1228 self.vars_list = None
1229
1231 if hasattr(self,'_orig_report_callback_exception'):
1232 self._tk.report_callback_exception = self._orig_report_callback_exception
1233
1235 success = 0
1236 for maybe_stimkey, maybe_control_frame, maybe_title in self.client_list:
1237 if stimkey == maybe_stimkey:
1238 control_frame_klass = maybe_control_frame
1239 success = 1
1240
1241 if not success:
1242 raise RuntimeError("Could not find valid client for server stimkey %s"%stimkey)
1243
1244 if hasattr(self, 'stim_frame'):
1245
1246 self.stim_frame.destroy()
1247 del self.stim_frame
1248
1249 self.stim_frame = control_frame_klass(self,suppress_go_buttons=1)
1250 if stimkey == "dropin_server":
1251 self.stim_frame.gen_var_widgets(self.demoscript_filename, self.vars_list)
1252 self.stim_frame.connect(self.server_hostname,self.server_port)
1253 self.stim_frame.grid( **self.stim_frame_cnf )
1254
1255 global loopable_variables
1256 loopable_variables = self.stim_frame.get_loopable_variable_names()
1257 if hasattr(self, 'loop_frame'):
1258
1259 self.loop_frame.destroy()
1260 del self.loop_frame
1261 self.loop_frame = ScrollListFrame(master=self,
1262 container_class=LoopContainedObject)
1263 self.loop_frame.grid( **self.loop_frame_cnf )
1264
1265 self.autosave_basename.set( self.stim_frame.get_shortname() )
1266
1267 self.stimulus_tk_var.set( self.stim_frame.get_shortname() )
1268
1269 self.progress.labelText = "Ready"
1270 self.progress.updateProgress(0)
1271
1273
1274 if new_stimkey is None:
1275 new_stimkey = self.stimulus_tk_var.get()
1276
1277 found = 0
1278 for maybe_stimkey, maybe_control_frame, maybe_title in self.client_list:
1279 if new_stimkey == maybe_stimkey:
1280 new_control_frame_klass = maybe_control_frame
1281 new_stimkey = maybe_stimkey
1282 found = 1
1283 break
1284
1285 if not found:
1286 raise RuntimeError("Don't know about stimkey %s"%new_stimkey)
1287
1288 if new_control_frame_klass != self.stim_frame.__class__ or new_stimkey == "dropin_server":
1289
1290 root = self.winfo_toplevel()
1291 old_cursor = root["cursor"]
1292 root["cursor"] = "watch"
1293 root.update()
1294 try:
1295
1296 self.progress.labelText = "Changing stimulus..."
1297 self.progress.updateProgress(0)
1298
1299 self.ephys_server.set_next_stimkey( new_stimkey )
1300
1301
1302 self.stim_frame.quit_server()
1303
1304
1305
1306
1307
1308 self.ephys_server.get_stimkey()
1309
1310 self.switch_to_stimkey( new_stimkey)
1311 finally:
1312
1313 root["cursor"] = old_cursor
1314 root.update()
1315
1318
1320 self.stim_frame.send_values()
1321 if self.config_dir is not None:
1322 initialdir = self.config_dir
1323 else:
1324 initialdir = VisionEgg.config.VISIONEGG_USER_DIR
1325 filename = tkFileDialog.asksaveasfilename(
1326 parent=self,
1327 defaultextension=".ve_cfg",
1328 filetypes=[('Configuration file','*.ve_cfg')],
1329 initialdir=initialdir)
1330 if not filename:
1331 return
1332 fd = open(filename,"wb")
1333 save_dict = {'stim_type':self.stim_frame.get_shortname(),
1334 'loop_list':self.loop_frame.list,
1335 'stim_frame_dict':self.stim_frame.get_parameters_dict(),
1336 'autosave':self.autosave.get(),
1337 'autosave_dir':self.autosave_dir.get(),
1338 'autosave_basename':self.autosave_basename.get()}
1339 pickle.dump( save_dict, fd )
1340 self.config_dir = os.path.split(filename)[0]
1341
1343 if self.config_dir is not None:
1344 initialdir = self.config_dir
1345 else:
1346 initialdir = VisionEgg.config.VISIONEGG_USER_DIR
1347 filename = tkFileDialog.askopenfilename(
1348 parent=self,
1349 defaultextension=".ve_cfg",
1350 filetypes=[('Configuration file','*.ve_cfg')],
1351 initialdir=initialdir,
1352 )
1353 if not filename:
1354 return
1355 self.config_dir = os.path.split(filename)[0]
1356 fd = open(filename,"rb")
1357 file_contents = fd.read()
1358 file_contents = file_contents.replace('\r\n','\n')
1359 memory_file = StringIO.StringIO(file_contents)
1360 load_dict = pickle.load(memory_file)
1361 if load_dict['stim_type'] != self.stim_frame.get_shortname():
1362 self.change_stimulus(new_stimkey=load_dict['stim_type']+"_server")
1363 self.loop_frame.list = load_dict['loop_list']
1364 self.loop_frame.update_now()
1365 self.stim_frame.set_parameters_dict( load_dict['stim_frame_dict'] )
1366 self.autosave.set(load_dict['autosave'])
1367 self.autosave_dir.set(load_dict['autosave_dir'])
1368 self.autosave_basename.set(load_dict['autosave_basename'])
1369
1370 self.stim_frame.update_tk_vars()
1371
1373 filename = tkFileDialog.askopenfilename(
1374 parent=self,
1375 defaultextension=".py",
1376 filetypes=[('Auto-saved parameter file','*.py')])
1377 if not filename:
1378 return
1379 locals = {}
1380 load_dict = orig_load_dict.copy()
1381 execfile(filename,locals,load_dict)
1382 if load_dict['stim_type'] != self.stim_frame.get_shortname():
1383 self.change_stimulus(new_stimkey=load_dict['stim_type']+"_server")
1384 self.loop_frame.list = []
1385 self.loop_frame.update_now()
1386 new_params = {}
1387 exception_info = []
1388 for param_name in dir(self.stim_frame.meta_params):
1389 if param_name[:2] != "__":
1390 try:
1391 new_params[param_name] = load_dict[param_name]
1392 except Exception, x:
1393 exception_info.append(sys.exc_info())
1394 else:
1395 del load_dict[param_name]
1396 for exc_type, exc_value, exc_traceback in exception_info:
1397
1398 VisionEgg.GUI.showexception(exc_type,exc_value,"")
1399 self.stim_frame.set_parameters_dict( new_params )
1400 self.autosave_basename.set(load_dict['stim_type'])
1401
1402 try:
1403 override_t_abs_sec = load_dict['go_loop_start_time_abs_sec']
1404 except Exception, x:
1405 tkMessageBox.showwarning("No absolute time parameter",
1406 "No absolute time parameter when loading file",
1407 parent=self)
1408 else:
1409 if not self.override_t_abs_on.get():
1410 self.override_t_abs_on.set(1)
1411 tkMessageBox.showwarning("Overriding absolute time parameter",
1412 "Overriding absolute time parameter on server. "+\
1413 "Remember to turn this option off (in Configure "+\
1414 "/ Calibrate menu) when done.",
1415 parent=self)
1416 self.override_t_abs_sec.set(repr(override_t_abs_sec))
1417
1418 self.stim_frame.update_tk_vars()
1419 return load_dict
1420
1422 self.demoscript_filename = tkFileDialog.askopenfilename(
1423 parent=self,
1424 defaultextension=".py",
1425 filetypes=[('Vision Egg Demo Script','*.py')])
1426
1427 if not self.demoscript_filename:
1428 return
1429 else:
1430
1431 root = self.winfo_toplevel()
1432 old_cursor = root["cursor"]
1433 root["cursor"] = "watch"
1434 root.update()
1435 try:
1436 fd1 = open(self.demoscript_filename, 'r')
1437 demoscript = ""
1438
1439
1440
1441
1442
1443
1444 self.vars_list = []
1445
1446 lines = fd1.read().splitlines()
1447 keep_lines = []
1448 while len(lines):
1449 myString = lines.pop(0)
1450 if myString.find("get_default_screen()") != -1:
1451 append_flag = 0
1452 elif myString.find("watch_exceptions()") != -1:
1453 append_flag = 0
1454 elif myString.find("start_default_logging()") != -1:
1455 append_flag = 0
1456 elif myString.find("#%f") == 0:
1457 self.vars_list.append([VarTypes.getID("float"), myString.replace("#%f", "").split()[0]])
1458 append_flag = 0
1459 elif myString.find("#%i") == 0:
1460 self.vars_list.append([VarTypes.getID("integer"), myString.replace("#%i", "").split()[0]])
1461 append_flag = 0
1462 elif myString.find("#%s") == 0:
1463 self.vars_list.append([VarTypes.getID("string"), myString.replace("#%s", "").split()[0]])
1464 append_flag = 0
1465 else:
1466 append_flag = 1
1467
1468 if append_flag == 1:
1469 keep_lines.append( myString )
1470
1471 fd1.close()
1472 demoscript = '\n'.join(keep_lines)
1473
1474
1475
1476 try:
1477 AST = parser.suite(demoscript)
1478
1479 for var in self.vars_list:
1480 var_val = AST_ext.extract_from_AST(AST, var[1])
1481 if var[0] == VarTypes.getID("string"):
1482 var_val = var_val[1:len(var_val) - 1]
1483 var.append(var_val)
1484
1485 del AST
1486
1487
1488
1489
1490 self.ephys_server.build_AST(demoscript)
1491
1492 self.change_stimulus(new_stimkey="dropin_server")
1493
1494 except (parser.ParserError, SyntaxError):
1495 tkMessageBox.showerror("Error", "Invalid demo script!")
1496 err_fd = file('/home/astraw/tmp/err.py',mode='w')
1497 err_fd.write(demoscript)
1498 finally:
1499
1500 root["cursor"] = old_cursor
1501 root.update()
1502
1511
1513 dialog = Tkinter.Toplevel(self)
1514 frame = Tkinter.Frame(dialog)
1515 frame.winfo_toplevel().title("Timing Calibration - Vision Egg")
1516 Tkinter.Label(frame,
1517 font=("Helvetica",12,"bold"),
1518 text="Stimulus onset timing").grid(row=0,column=0)
1519 Tkinter.Label(frame,
1520 text="Use a light detector to verify the onset of a trial."
1521 ).grid(row=1,column=0)
1522 Tkinter.Checkbutton( frame,
1523 text="Black box (always) with white box (during trial)",
1524 variable=self.stim_onset_cal_tk_var,
1525 command=self.update_stim_onset_cal).grid(row=2,column=0)
1526
1527 x,y,width,height = self.ephys_server.get_stim_onset_cal_location()
1528
1529 location_frame = Tkinter.Frame(frame)
1530 location_frame.grid(row=3,column=0)
1531 self.stim_onset_x = Tkinter.DoubleVar()
1532 self.stim_onset_x.set(x)
1533 self.stim_onset_y = Tkinter.DoubleVar()
1534 self.stim_onset_y.set(y)
1535 self.stim_onset_width = Tkinter.DoubleVar()
1536 self.stim_onset_width.set(width)
1537 self.stim_onset_height = Tkinter.DoubleVar()
1538 self.stim_onset_height.set(height)
1539
1540 Tkinter.Label( location_frame, text="Center X:").grid(row=0,column=0)
1541 Tkinter.Entry( location_frame, textvariable=self.stim_onset_x,width=5).grid(row=0,column=1)
1542 Tkinter.Label( location_frame, text="Center Y:").grid(row=0,column=2)
1543 Tkinter.Entry( location_frame, textvariable=self.stim_onset_y,width=5).grid(row=0,column=3)
1544 Tkinter.Label( location_frame, text="Width:").grid(row=1,column=0)
1545 Tkinter.Entry( location_frame, textvariable=self.stim_onset_width,width=5).grid(row=1,column=1)
1546 Tkinter.Label( location_frame, text="Height:").grid(row=1,column=2)
1547 Tkinter.Entry( location_frame, textvariable=self.stim_onset_height,width=5).grid(row=1,column=3)
1548
1549 Tkinter.Button( frame,
1550 text="update position and size",
1551 command=self.set_stim_onset_cal_position).grid(row=4,column=0)
1552 self.set_stim_onset_cal_position()
1553 frame.pack(expand=1,fill=Tkinter.BOTH)
1554
1556 dialog = Tkinter.Toplevel(self)
1557 frame = GammaFrame(dialog,
1558 self.ephys_server)
1559 frame.pack(expand=1,fill=Tkinter.BOTH)
1560
1562 self.autosave_dir.set( os.path.abspath( tkFileDialog.askdirectory() ) )
1563
1566
1570
1572 x = self.stim_onset_x.get()
1573 y = self.stim_onset_y.get()
1574 width = self.stim_onset_width.get()
1575 height = self.stim_onset_height.get()
1576 self.ephys_server.set_stim_onset_cal_location(center=(x,y),size=(width,height))
1577
1578
1580 super_loop_list = self.loop_frame.get_list_uncontained()
1581
1582
1583
1584
1585 global need_rest_period
1586 need_rest_period = 0
1587
1588 if not len(super_loop_list):
1589 return
1590
1591
1592 def process_loops(depth):
1593
1594 class LoopInfoFrame(Tkinter.Frame):
1595 def __init__(self, master=None, **kw):
1596 Tkinter.Frame.__init__(self,master,**kw)
1597 Tkinter.Label(self,
1598 text="Doing sequence").grid(row=0,column=0)
1599 self.status_tk_var = Tkinter.StringVar()
1600 Tkinter.Label(self,
1601 textvariable = self.status_tk_var).grid(row=1, column=0)
1602 self.cancel_asap = 0
1603 Tkinter.Button(self,
1604 text="Cancel",command=self.cancel).grid(row=2,column=0)
1605 self.focus_set()
1606 self.grab_set()
1607 def cancel(self, dummy_arg=None):
1608 self.cancel_asap = 1
1609
1610 global need_rest_period
1611
1612 global loop_info_frame
1613 if depth == 0:
1614 top = Tkinter.Toplevel(self)
1615 loop_info_frame = LoopInfoFrame(top)
1616 loop_info_frame.pack()
1617
1618 loop_list = super_loop_list[depth]
1619
1620
1621
1622
1623 max_depth = len(super_loop_list)-1
1624
1625
1626
1627 loop = loop_list[0].get_contained()
1628
1629
1630
1631
1632
1633 while not loop.is_done() and not loop_info_frame.cancel_asap:
1634 for loop_element in loop_list:
1635 if loop_element.get_contained().parameters.variable != "<repeat>":
1636 self.stim_frame.set_loopable_variable(loop_element.get_contained().parameters.variable,loop_element.get_contained().get_current())
1637 if depth < max_depth:
1638 process_loops(depth+1)
1639 elif depth == max_depth:
1640 if need_rest_period:
1641 self.progress.labelText = "Resting"
1642 self.sleep_with_progress(loop.parameters.rest_duration_sec)
1643 self.do_single_trial()
1644 need_rest_period = 1
1645 else:
1646 raise RuntimeError("Called with max_depth==-1:")
1647 for loop_element in loop_list:
1648 loop_element.get_contained().advance()
1649 for loop_element in loop_list:
1650 loop_element.get_contained().reset()
1651 if depth == 0:
1652 top.destroy()
1653
1654
1655 process_loops(0)
1656
1658
1659 if not self.autosave.get():
1660 file_stream = None
1661 else:
1662 duration_sec = self.stim_frame.get_duration_sec()
1663 (year,month,day,hour24,min,sec) = time.localtime(time.time()+duration_sec)[:6]
1664 trial_time_str = "%04d%02d%02d_%02d%02d%02d"%(year,month,day,hour24,min,sec)
1665 if self.param_file_type_tk_var.get() == "Python format":
1666
1667 filename = self.autosave_basename.get() + trial_time_str + "_params.py"
1668 fullpath_filename = os.path.join( self.autosave_dir.get(), filename)
1669 file_stream = open(fullpath_filename,"w")
1670 elif self.param_file_type_tk_var.get() == "Matlab format":
1671
1672 filename = self.autosave_basename.get() + trial_time_str + "_params.m"
1673 fullpath_filename = os.path.join( self.autosave_dir.get(), filename)
1674 file_stream = open(fullpath_filename,"w")
1675 else:
1676 raise ValueError('Unknown file format: "%s"'%(self.param_file_type_tk_var.get(),))
1677
1678
1679 self.do_single_trial_pre(file_stream)
1680 self.do_single_trial_work()
1681 self.do_single_trial_post(file_stream)
1682
1683
1684 if self.autosave.get():
1685 file_stream.close()
1686
1688
1689 self.stim_frame.send_values()
1690
1691
1692 if self.autosave.get():
1693 duration_sec = self.stim_frame.get_duration_sec()
1694 (year,month,day,hour24,min,sec) = time.localtime(time.time()+duration_sec)[:6]
1695 if self.param_file_type_tk_var.get() == "Python format":
1696 file_stream.write("stim_type = '%s'\n"%self.stim_frame.get_shortname())
1697 file_stream.write("finished_time = %04d%02d%02d%02d%02d%02d\n"%(year,month,day,hour24,min,sec))
1698 parameter_list = self.stim_frame.get_parameters_as_py_strings()
1699 for parameter_name, parameter_value in parameter_list:
1700 file_stream.write("%s = %s\n"%(parameter_name, parameter_value))
1701 elif self.param_file_type_tk_var.get() == "Matlab format":
1702 file_stream.write("stim_type = '%s';\n"%self.stim_frame.get_shortname())
1703 file_stream.write("finished_time = %04d%02d%02d%02d%02d%02d;\n"%(year,month,day,hour24,min,sec))
1704 parameter_list = self.stim_frame.get_parameters_as_m_strings()
1705 for parameter_name, parameter_value in parameter_list:
1706 file_stream.write("%s = %s;\n"%(parameter_name, parameter_value))
1707 else:
1708 raise RuntimeError("Unknown parameter file type")
1709
1711
1712 root = self.winfo_toplevel()
1713 self.old_cursor = root["cursor"]
1714 root["cursor"] = "watch"
1715 root.update()
1716 try:
1717
1718 self.progress.labelText = "Doing trial..."
1719 self.progress.updateProgress(0)
1720
1721 duration_sec = self.stim_frame.get_duration_sec()
1722 if duration_sec > 0:
1723 if self.override_t_abs_on.get():
1724 new_t_abs_str = self.override_t_abs_sec.get()
1725 self.ephys_server.set_override_t_abs_sec( new_t_abs_str )
1726
1727 self.stim_frame.go()
1728 self.sleep_with_progress(duration_sec)
1729 while self.ephys_server.is_in_go_loop():
1730 time.sleep(0.1)
1731
1732 if self.notify_on_dropped_frames.get():
1733 if self.ephys_server.were_frames_dropped_in_last_go_loop():
1734 tkMessageBox.showwarning("Dropped frame(s)",
1735 "During the last trial, at least 1 frame was dropped.",
1736 parent=self)
1737 else:
1738 if self.stim_frame.send_values():
1739 self.ephys_server.run_demoscript()
1740 self.stim_frame.quit_server()
1741 finally:
1742 root["cursor"] = self.old_cursor
1743 root.update()
1744
1745
1746 self.progress.labelText = "Ready"
1747 self.progress.updateProgress(0)
1748
1749 - def do_single_trial_post(self, file_stream):
1750
1751 if self.autosave.get():
1752 frames_dropped = self.ephys_server.were_frames_dropped_in_last_go_loop()
1753 go_loop_start_time = self.ephys_server.get_last_go_loop_start_time_absolute_sec()
1754 if self.param_file_type_tk_var.get() == "Python format":
1755 file_stream.write("frames_dropped = %s # boolean\n"%str(frames_dropped))
1756 file_stream.write("go_loop_start_time_abs_sec = %s\n"%repr(go_loop_start_time))
1757 elif self.param_file_type_tk_var.get() == "Matlab format":
1758 file_stream.write("frames_dropped = %s; %% boolean\n"%str(frames_dropped))
1759 file_stream.write("go_loop_start_time_abs_sec = %s;\n"%repr(go_loop_start_time))
1760 else:
1761 raise RuntimeError("Unknown parameter file type")
1762
1764 if duration_sec == 0.0:
1765 return
1766 start_time = time.time()
1767 stop_time = start_time + duration_sec
1768 percent_done = 0
1769 while percent_done < 100:
1770 if sys.platform != 'darwin':
1771 self.progress.updateProgress(percent_done)
1772 time.sleep(0.01)
1773 percent_done = (time.time() - start_time)/duration_sec*100
1774
1780
1788
1796
1797 if __name__ == '__main__':
1798 hostname = os.getenv("ephys_server_hostname","")
1799 port = int(os.getenv("ephys_server_port","7766"))
1800 result = get_server(hostname=hostname,port=port)
1801 if result:
1802 hostname,port = result
1803 app_window = AppWindow(client_list=client_list,
1804 server_hostname=hostname,
1805 server_port=port)
1806
1807 app_window.winfo_toplevel().wm_iconbitmap()
1808 app_window.pack(expand=1,fill=Tkinter.BOTH)
1809 app_window.mainloop()
1810