part02-develope.tex 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. %!TEX root = ../Kapture2 Docu.tex
  2. \chapter{GUI Developement}
  3. \label{ch:dev}
  4. \section{Pagackelist}
  5. \begin{itemize}
  6. \item PyQT4
  7. \item sip
  8. \item pyqtgraph
  9. \item numpy
  10. \item psutil
  11. \item pyepics
  12. \item setuptools
  13. \end{itemize}
  14. \section{misc}
  15. \label{ch:dev:misc}
  16. The Code is written to be working on both Python2 and Python3. At the moment this guide mostly only provides infos for the modules I developed or changed.
  17. Before the Idea of KAPTURE2 came to live there was the idea to put multiple Kapture1 boards in on PC. So to the GUI a multi Kapture support was added. Unfortunately not in a perfect OOP fashion and therefore the code is now a little bit inconsistent. The new changes for KAPTURE2 mostly ignore things from the multi kapture implementation and therefore the current GUI version does not really support multi KAPTURE anymore - sry.
  18. Also it should work also on the old KAPTURE-1 System but it has not been tested.
  19. The configfiles and the icons etc are located in \textit{.kcg2} to avoid conflicts with the old KAPTURE-1 GUI.
  20. \section{Modules}
  21. This is a not a complete list of all the modules with more or less small informations.
  22. \subsubsection*{base/backend/board/communication}
  23. This contains the \code{class PCI}, witch wraps the system-calls for the pci communication to the FPGA.
  24. It also creates one instance of the class with the name \code{pci}. By using
  25. \begin{lstlisting}
  26. from .communication import pci
  27. \end{lstlisting}
  28. one can then read and write to the FPGA.
  29. There is also a dummy class which is selected when the gui is started with --testing parameter. It does not read or write to the hardware and can be therefore used while developing on a system without a KAPTURE board - even on a windows system.
  30. \subsubsection*{base/backend/board/board\_config}
  31. This contains the \code{class BoardConfiguration}. It is the central control Class for all the KAPTURE settings. (Like Delay, Turns to observe ...) It uses a dictionary to stores all the settings.
  32. It is mainly base on observers. The function \code{update(key, value)} is used to change a setting. It then calls the observers. There are 3 Types of observers
  33. \begin{enumerate}
  34. \item observers\_write:\\ those are controlled by the class it self. They write the settings to the board.
  35. \item observers\_for\_all:\\ they are called every time one setting is changed - independent of the key
  36. \item observers:\\ they are called when the corresponding key changes. Those are mainly used to update the GUI.
  37. \end{enumerate}
  38. The \code{update} function has an additional parameter \code{write=True} it controls weather the observers\_write will be called or not. By default it is set to true. This is only needed for the function \code{read\_from\_board}, wich reads the settings from the FPGA, to prevent it from unnecessary rewrite it.
  39. In widgets one can register a observer via the function \code{observe(who, callback, key)}\\
  40. who is used as an identifier when one wants to remove the observer. It can be nearly everything - Object, variable - usually in the GUI it is the Object that will be changed (Like the label that is updated). \\
  41. callback is the function that will be called and needs to have one parameter by which the new value will be passed.\\
  42. key is the setting that will be observed.
  43. When the widget will be deleted all corresponding observers need to be removed by \code{unobserve(who, key)}!
  44. One example from acquiresettings widget
  45. \begin{lstlisting}
  46. def __init__(...):
  47. self.board_config = board.get_board_config(board_id)
  48. self.fileSizeOutLabel = self.createLabel("??")
  49. self.board_config.observe(self.fileSizeOutLabel, self.set_filesize, 'turns_observe')
  50. .
  51. .
  52. def set_filesize(self, state):
  53. .
  54. .
  55. def closeEvent(self, event):
  56. self.board_config.unobserve(self.fileSizeOutLabel, 'turns_observe')
  57. .
  58. .
  59. \end{lstlisting}
  60. \subsubsection*{base/backend/board/sequences}
  61. The sequences are used to initialize the board. They are series of commands send to the FPGA. It is controlled by the \code{board_config} and from the backendinterface.
  62. The module contains two function:\\
  63. \code{def read_sequence(board_version)}\\
  64. \code{def run_sequnce(board_id, sequence, progressbar=None)}
  65. The sequences are stored in json files in \textit{base/backend/board/sequences/sequence\_x.json} with x to be the \code{board_version}. The \code{board_version} is read by \code{board_config} from the FPGA.
  66. All sequences in the \code{"sequence\_names"} list will have a Button.\\
  67. The \code{"initialization\_sequence\_order"} specifies which sequences will be run for \textit{Prepare Board}
  68. One Sequence is represented like this
  69. \begin{lstlisting}
  70. "demo_sequence": {
  71. "Comment": "Text shown on Button",
  72. "status_val": "", #some Sequences set these to enable functions inside the gui
  73. "sequence": [
  74. [
  75. "value", "reg",
  76. "dialog text", #If not an empty string a popup is shown before sending
  77. "comment", #Printed in Logfile
  78. "key", "value", #Optional: used to update the board_config
  79. "key", "value" # It calls config.update(key, value, write=False)
  80. ],
  81. [
  82. "value", "reg",
  83. "", #No popup
  84. "another command without update the board_config"
  85. ],
  86. [
  87. "value", "reg",
  88. "",
  89. "",
  90. "key", "value", #only one update of board_config
  91. ]
  92. ]
  93. },
  94. \end{lstlisting}
  95. \subsubsection*{base/backend/DataSet}
  96. Contains measured data. It has all the needed functions to open files, decode them and prepare them for plotting etc.
  97. This Class is also used outside the KCG.
  98. \subsubsection*{base/backend/TimeScan}
  99. Class to read and generate timescans files.
  100. This Class is also used outside the KCG.
  101. \subsubsection*{base/backend/CalibrationHandle}
  102. This Class Handles the Calibration Files and is used by the \code{DataSet} and \code{TimeScan}.
  103. It contains also an instance of itself which should be used. So don't create a new one.
  104. \begin{lstlisting}
  105. theCalibration = CalibrationHandle()
  106. \end{lstlisting}
  107. When ever one cals \code{theCalibration.openFile(...)} it returns a identifier.
  108. \subsubsection*{base/backendinterface}
  109. The most messy module. It contains a vast amount of functions.
  110. Including:\\
  111. wrapper functions for the \code{board_control} \\
  112. functions to run the sequences\\
  113. everything for data acquisition
  114. \subsubsection*{widgets/} The most of the controlling is in the widgets. They can be understood as some kind of modules. To add new functionality to the GUI - like advanced analytic - one can just add a new Widget.
  115. there are by now:
  116. \begin{itemize}
  117. \item AcquireSettingsWidget
  118. \item PlotWidget
  119. \item SingleReadWidget
  120. \item TimeingWidget
  121. \item TimescanWidget
  122. \item EpicsWidget\\
  123. Has one speciality: it is initialized in \textit{base/kcg} via
  124. \begin{lstlisting}
  125. if config.use_epics:
  126. from ..widgets import EpicsWidget
  127. EpicsWidget.epicsConfig = EpicsWidget.EpicsConfig()
  128. \end{lstlisting}
  129. %\item AdcWidget
  130. \item UpdateCalibrationWidget
  131. \item CorrelationWidget
  132. \end{itemize}
  133. To activate a widget put the module name in widgets/\_\_init\_\_.py
  134. If a widget should be updated everytime a new Data is acquired. register a observer onto \code{"lastDataSet"}. Like it is done in the \code{PlotWidget}
  135. \begin{lstlisting}
  136. def initUI(self):
  137. self.board_config.observe(self, self.observeDataSet, 'lastDataSet')
  138. def observeDataSet(self, data):
  139. self.plot_live(data=data)
  140. def closeEvent(self, event):
  141. self.board_config.unobserve(self, 'lastDataSet')
  142. \end{lstlisting}
  143. Do not forget to unobserve!
  144. \subsubsection*{config.py}
  145. Module to handle the config file. It also provides some helperfunctions for accessing the current working path as well as the installation path. Also is it the place where the colors for the Plotwidget are defined.
  146. \newpage
  147. \section{FPGA stuff}
  148. \TextGrafik[H]{Bank Register}{pl:bank}{1}{BankRegister.PNG}