API

Basis interface

Het eerste keuzescherm bevat twee keuzes voor de gebruiker. De gebruiker kan kiezen tussen een studentenmeting of een meting met de volledige functionaliteit. De studentenmeting is een vereenvoudigde versie van de meting met de volledige functionaliteit.

De class met zijn methodes en attributen gebruikt voor dit scherm staan hieronder.

class src.Base_interface.Base_interface

Bases: Tk

Base interface voor de GUI’s

Link in programma:

Base -> Student_startup -> Student_load -> Student_results Base -> Physics_interface -> student_load -> Physics_results -> Student_results

-> sluit na het laden van de volgende interface/indrukken knop -> sluit NIET na het laden van de volgende interface/indrukken knop

attributes:

__init__()

Initialiseer de GUI

student_button()

Maak een knop aan die de student interface opent

physics_button()

Maak een knop aan die de physics interface opent

Parameters:

linked_event (class) – de class van de physics interface

Returns:

None

build_gui()

Plaatst de buttons voor student en physics op de GUI

Physics Interface

Het hoofdscherm van de applicatie is de Physics Interface. Hierin kan de gebruiker de meting instellen en uitvoeren. De inteface bestaat uit verschillende knoppen met functionaliteiten. Hieruit kunnen mogelijk 3 andere schermen worden geopend: - Measurement Settings - Save Measurement - Student measurement

Ieder scherm dat kan worden geopend bevindt zich in zijn eigen file en class. Hieronder staan de atributen en methodes van de physics intefrace.

src.Physics_Interface.Physics_interface.multiple_data(samples, meastime: float = 0.01) ndarray' id='140056477809616'>]

Genereer data voor de GUI als simulatie voor hardware.py als deze niet beschikbaar is.

Returns:

tijd, data

src.Physics_Interface.Physics_interface.single_data()

Mock functie voor single data als hardware.py niet beschikbaar is. :param tref: referentie tijd :type tref: float

Returns:

Array met willekeurige data

Return type:

np.ndarray

class src.Physics_Interface.Physics_interface.Base_physics

Bases: Tk

Eerste start scherm, alles wat direct wordt gebruikt kan niet na instantiatie worden aangepast maar zou direct in de code moeten worden aangepast. Deze waarden staan dus gehardcode in de code.

__init__()

Initialisatie van de GUI

config_path

Pad naar configuratie bestand, wordt direct in de __init__ gebruikt

geom

Geometrie van het scherm, wordt direct in de __init__ gebruikt

row

Row counter voor de rechter helft, wordt gebruikt om de positie van de widgets te bepalen

rowfig

Row counter voor de linker helft, wordt gebruikt om de positie van het figuur te bepalen

time_start

Referentie tijd die van self.data_time wordt afgehaald om naar seconden te rekenen

measurementtype

Type meting uit de config, 0 is een meting van N-punten 1 is een conitinue meting

nrofmeasurements

Aantal metingen per meetserie voor meettype 0

msperframe

Verversingstijd van de grafiek in ms

xastype

Type van de x-as, 0 is tijd, 1 is samples

yastype

Type van de y-as, 0 is spanning, 1 is intensiteit, 2 is transmissie, 3 is OD-waarde

msperdata

Verversingstijd van de realtime data in ms

std

Standaarddeviatie van de metingen in std * sigma

path2ref

Pad naar het referentie bestand

nrofmeasurementsstudent

Aantal metingen per meetserie

student_measurementtime

Tijd tussen metingen voor een studentmeting

student_measurementtype

Type meting uit de config, 0 is een meting met als resultaat transmissie en 1 met OD waarde

student_meas_marge

Marge voor de verificatie meting voordat een student meting is gestart

xaxis

Tijd array voor data verwerking en plotten

yaxis

Voltage array voor data verwerking en plotten

student_voltage

Voltage array voor student metingen, wordt gebruikt voor dataanlyse van meest recente data

student_time

Tijd array voor student metingen, wordt gebruikt voor dataanlyse van meest recente data

Build_GUI_physics(updated=True)
Bouw de GUI op en voeg de volgende elementen toe:
  • De linker helft van het scherm wordt opgevuld met een grafiek dit wordt gedaan met de functie ..py:class Base_physics.graph_topleft

  • De rechter helft van het scherm wordt opgevuld met een aantal ‘tabellen’ met meetwaarden en resultaten van de realtime data en de meest recente student meting (die is opgeslagen in een file)

De tabellen worden gemaakt met de functie ..py:class Base_physics.data_box

Parameters:

updated (bool) – True om de update job te starten aan het einde van het opbouwen van de GUI. Voor bugfixing

Returns:

None

initialise_config_data() None

Lees de config file ui, het pad hiernaartoe is eerder gedefinieerd en hard coded om te voorkomen dat er problemen ontstaan met het vinden en uitlezen van de config file.

Returns:

None

savecfg_to_config()

Converteer alle variabelen naar een config met de ConfigParser module en schrijf deze weg naar de variabele config.

Returns:

None

read_student_measurement()

Lees het pad met de student meting uit, hardcoded. Als er geen verandering in de data is, return dan False, anders return True.

Returns:

Wel of geen verandering in de data

Return type:

bool

graph_topleft()

Maak een grafiek en plaats deze in de linkerhelft van de GUI. De grafiek is een animatie om de data real time te kunnen plotten. Deze animatie wordt aangestuurd door de functie self.animate().

Returns:

None

animate(i: int) <Mock name='mock.lines.Line2D' id='140056520891856'>

Functie die de data van de grafiek update. De data wordt uit de attributes self.xaxis en self.yaxis gehaald welke worden geupdate door de functie self.update_vars(). :param i: Iteratie van de functie :type i: int

Returns:

De lijn van de grafiek

Return type:

matplotlib.lines.Line2D

data_box(txt_labels: List[List[str]], entries: List[List[str]], explain_text: str, buttons: bool = False, edit_state: bool = False, commands: Optional[List] = None, updated: bool = False) List[Entry]

Een tabel met 2x3 entries en hieraan een label met uitleg, boven de box met entries/labels staat een label met uitleg welke ook meegegeven kan worden. De entries kunnen ook buttons zijn met een gekoppelde command.

Voorbeeld om de variabelen verder in het script te kunnen updaten:

for entry in range(len(stringvars)):
    stringvars[en].set(stringvars[entry]) # Update de stringvars
    # configureer de entries om nieuwe waarden te accepteren
    entries_list[en].config(state="normal")
    # Vul de nieuwe waarden van de stringvar in in de entries
    entries_list[en].setvar(str(stringvars[en]), str(stringvars.get()))
    # Maak de entries weer readonly
    entries_list.config(state="readonly")
Parameters:
  • txt_labels (List[List[str]]) – Lijst van labels voor de entries gegeven als [[labels van row 1], [labels van row 2]]

  • entries (List[List[str or float]]) – Lijst van, standaard ingevulde waarden, voor de entries in het zelfde format als txt_labels deze kunen geupdate worden als updated True is.

  • buttons (bool) – True als de entries buttons moeten zijn, hierbij wordt de entries parameter gebruikt als de labels weergegeven in de entry.

  • edit_state (bool) – True als de entries aangepast moeten kunnen worden, False als de entries niet aangepast mogen worden. Hierbij kan user input gevraagd worden.

  • updated – True als de entries geupdate moeten kunenn worden via de entries en stringvars die worden meegegeven in de return, False als de entries niet geupdate moeten worden.

  • commands (List[List[Callable]]) – Alleen van toepassing als buttons True is, dit is een lijst van commando’s die gekoppeld zijn aan de buttons in hetzelfde format als txt_labels en entries.

Returns:

In het geval dat edit_state, update of buttons true is worden de signatures van de entries en de tk.StringVar van de ingevulde waardes teruggegeven.

Return type:

Tuple[List[tk.Entry], List[tk.StringVar]] or None

read_ndatapoints() List[str]

Verwerk de binnengekomen data van de ADC die in de self.data_voltage en bereken hiermee de transmissie, intensiteit en OD waarde. Voor de OD waarde en transmissie wordt de referentie file gebruikt die staat gespecificeerd in de instellingen. De return is 6 strings voor de data_box.

Lijst van strings:
  • Laasts gemeten voltage

  • Gemiddelde voltage +- standaard deviatie

  • Intensiteit (via ..python:func:calculate_intesnity)

  • Transmissie (gemeten intensiteit/ ref intensiteit)

  • OD waarde (log10(1/transmissie))

Returns:

Een lijst van strings met de waardes van voltage, transmissie, intensiteit en OD waarde.

Return type:

List[str]

update_student_measurement()

Verwerk de binnengekomen data van de ADC die in de self.student_voltage staat opgeslagen en bereken hiermee de transmissie, intensiteit en OD.

Returns:

Een lijst met het gemiddelde voltage, de standaard deviatie, de intensiteit, de transmissie en de OD waarde.

Return type:

List[str]

measurement_thread(q, tstart, measurementtype, nrofmeasurements, last_time, prev_data_time, prev_data_voltage, meas_time=0.01)

Start een meting op in een aparte thread. De meting wordt gestart door de functie generate_data() of single_data() aan te roepen. :param q: Queue waar de data in wordt opgeslagen. :type q: Queue

Parameters:
  • tstart (float) – Starttijd van de meting.

  • measurementtype (str) – Type meting, 0 voor een meting met een vast aantal datapunten, 1 voor een meting met een variabel aantal datapunten.

  • nrofmeasurements (str) – Aantal datapunten dat gemeten moet worden.

  • last_time (float) – Tijd van het laatste datapunt.

  • prev_data_time (numpy.ndarray) – Tijd van de vorige datapunten.

  • prev_data_voltage (numpy.ndarray) – Voltage van de vorige datapunten.

  • meas_time (float) – Tijd tussen de datapunten.

Returns:

None

update_vars(*args) str

Functie die iedere 1000ms wordt aangeroepen en de data van de ADC verwerkt en de data boxen/grafiek update. Eerst worden alle variablen geupdate in de data boxen vervolgenswordt de as berekend a.d.h.v. de self.data_voltage en de self.data_time en gegeven instellingen uit config.

Volgorde van verloop:

  1. Lees de meest recente studentmeting uit, ‘MeesteRecenteMeting.txt’

  2. Voor alle 6 de data entries in de recente meting en student box wordt de waarde geupdate volgens de volgorde in *args

  3. Verwerk de data uit de meest recente meting naar behoren van instellingen voor de x-as en y-as

  4. Roep de functie voor het updaten van de plot in de grafiek aan

  5. Roep recursief deze functie aan iedere 1000ms

Parameters:
  • args[0] – Lijst met verwerkte meest recente data uitgelezen uit de ADC

  • args[1] – Lijst met meest recent ingelezen data uit de studentmeting

Returns:

De naam van de Job aangemaakt via deze functie

Return type:

str

static calculate_intesnity(x)

Bereken de intensiteit van een enkele waarde of array van waarden. Functie via: https://learn.sparkfun.com/tutorials/ml8511-uv-sensor-hookup-guide/all

Wiskundig is dit een lineair verband met een offset van 1 en een helling van 15/2 ofwel:

\[y = \frac{15}{2}x + 1\]
Parameters:

x (Optional[float, np.ndarray]) – Voltage waarde of array van voltage waarden

Returns:

Intensiteit waarde of array van intensiteit waarden

reset_data()

Reset de data in de self.data_time en self.data_voltage arrays en daarmee ook de grafiek/databox. De data wordt gereset naar een enkele waarde, namelijk de laatst gemeten waarde.

Clear ook de queue van de thread zodat de oude data niet meer wordt teruggegeven in de self.data_time en self.data_voltage arrays

Returns:

None

save_data()

Sla de data op via een SaveData object, dit spawned een nieuw venster uit de SaveData klasse.

Dit slaat de voltage data op in de y-as en de tijd data op in de x-as.

Returns:

None

pause_meas()

Stop the update_vars job and set self.job to None

Returns:

None

start_meas()

Als er geen meting loopt, start een meting via de update_vars functie.

Returns:

None

start_settings()

Start een settings window via de Settings klasse.

Returns:

None

start_student_measurement()

Start een student measurement window via de Student_start_measurement klasse.

Returns:

None

destroy() None

Zorg ervoor dat alles netjes wordt afgesloten als het hoofdvenster wordt gesloten.

Returns:

None

Measurement Settings

In dit scherm kan de gebruiker de instellingen van de meting aanpassen. De gebruiker kan de volgende instellingen aanpassen: Voor de meting:

  • Het meettype (N-metingen tegelijk of iedere meting aan de bestaande grafiek toevoegen)

  • Het aantal metingen dat tegelijk wordt uitgevoerd.

Voor de grafiek:

  • De grootheid op de x-as (tijd of nr van metingen)

  • De grootheid op de y-as (spanning, intensiteit, transmissie of berekende OD waarden)

  • De verversingsfrequentie van de grafiek (standaard 1000 ms)

  • De stapsgrootte van de x-as

Een aantal algemene variabelen:

  • De sigma factor voor de berekening van de standaarddeviatie die wordt weergegeven.

  • Het pad naar de referentie meting voor verificatie van de opstelling en voor de berekening van OD/transmissie waarden.

Instellingen voor een studentenmeting: - Het aantal datapunten dat wordt verzameld en opgeslagen tijdens een meting. - De tijd van de algehele meting. - Het getoonde resultaat van de meting, OD waarde en transmissie. - Marge (in volt) voor de verificatie van de opstelling.

Hieronder staan de attributen en methodes van deze class.

class src.Physics_Interface.Physics_interface_Settings.Settings(parent)

Bases: Toplevel

alive = False

Window alive flag

__init__(parent)

Initialize the window

build_settings()

Maak de settings aan, plaats al de labels en link ze aan de juiste variabelen via attributen van de klasse.

Returns:

None

save_options()

Saves the options to the parent class from the entry fields

reset_options()

Resets the options to the default values

destroy() None

Destroys the frame

Save Measurement

Om data punten op te slaan kan de gebruiker dit scherm openen. Hierbij worden alle datapunten die zijn weergegeven in de grafiek naar een .txt file geschreven, dit is handig voor het maken van een snelle meting of hiermee grafieken in andere programma’s te maken. De save functie bevat twee opties het pad naar de directory waar het wordt opgeslagen en de naam van het bestand.

class src.Physics_Interface.Physics_interface_DataManipulation.SaveData(parent)

Bases: Toplevel

Window to save data to a path and filename

alive = False

Boolean to check if the SaveData is alive

__init__(parent)

Initialize the window

datax

X data to be saved

datay

Y data to be saved

stdy

Standard deviation of the y data to be saved

load_data_from_main(datax, datay, stdy)

Load data from the main window

Parameters:
  • datax (np.ndarray) – X data to be saved, from the main window

  • datay (np.ndarray) – Y data to be saved, from the main window

  • stdy (np.ndarray) – Standard deviation of the y data to be saved, from the main window

Returns:

None

save_data()

Save data to a path and filename, if no path is given, save to ../data

destroy() None

Destroy this and all descendants widgets.

class src.Physics_Interface.Physics_interface_DataManipulation.Saved_data_notif(parent)

Bases: Toplevel

Notification window to show the user that the data has been saved

__init__(parent)

Initialize the window :param parent: Parent window :type parent: tk.Toplevel

get_path(path, filename)

Get the path and filename to be shown in the notification from the SaveData window.

Parameters:
  • path (str) – Path to the saved file

  • filename (str) – Filename of the saved file

message()

Show the notification

Student Measurement interface

Aanvankelijk wordt de opstelling geverifieerd. Dit gebeurt zodra de knop “Student” in het basis interface wordt ingedrukt. Dit verifieering gebeurt in een aparte thread om ervoor te zorgen dat de GUI niet bevriest. Het gemiddelde van de referentie meting wordt vergeleken met de reference file aangegeven in de instellingen zoals laten zien hiervoor in de Measurement Settings. Als de gemiddelde waarde binnen de marge valt wordt komt de student in het metingscherm. In de code wordt hiervoor het scherm ververst met nieuwe labels en wordt de lopende balk verwijderd. Als de student op start meting drukt wordt de meting gestart, en uitgevoerd in een aparte thread. Het resultaat wordt dan laten zien. De queue is gedeeld tussen de threads om data te verzamelen en te laten zien in de grafiek. De student kan de meting stoppen door het programma te sluiten of de stop knop in te drukken.

class src.Student_Interface.Student_interface.Student_start_measurement

Bases: Tk

__init__()

Return a new Toplevel widget on screen SCREENNAME. A new Tcl interpreter will be created. BASENAME will be used for the identification of the profile file (see readprofile). It is constructed from sys.argv[0] without extensions if None is given. CLASSNAME is the name of the widget class.

nrofmeasurementsstudent

Het aantal meetpunten dat in een meting zit

student_measurementtime

De tijd die het kost om een meting uit te voeren

student_measurementtype

Wordt het resultaat weergeven als transmissie of OD waarde

marge

De marge die wordt gebruikt om te bepalen of de opstelling goed is

refdata

De referentie data

measure_frame(targfunction, label_text='Opstarten...', result_function=None)

Laat een progressiebalk zien zolang de meting verloopt en voer een functie uit met het resultaat van de meting.

Parameters:
  • targfunction (callable) – De functie die wordt uitgevoerd om de meting te starten, deze functie wordt uitgevoerd in een thread en moet een queue als argument hebben.

  • label_text (str) – De tekst die wordt weergegeven boven de progressiebalk.

  • result_function (callable) – De functie die wordt uitgevoerd met het resultaat van de meting, deze functie moet een een 2d numpy array als argument hebben.

Returns:

None

await_results(q: Optional[Queue] = None, function: Optional[callable] = None)
Controleer de queue herhaaldelijk of er al resultaten zijn gerappoteerd. Als er resultaten zijn, voer dan de meegegeven functie uit.

met deze resultaten en leeg de queue.

Parameters:
  • q (Queue) – De queue waar het resultaat in wordt gestopt.

  • function (function) – De functie die wordt uitgevoerd met het resultaat.

Returns:

None

update_startup(verification_succeeded: bool) None

Update de GUI na het opstarten van de meting. Als het is gelukt, dan wordt er een knop toegevoegd om de meting te starten. Als het niet is gelukt, dan wordt er een knop toegevoegd om het opnieuw te proberen. :param verification_succeeded: True als het is gelukt, False als het niet is gelukt. :type verification_succeeded: bool

Returns:

None

verification_measurement(q: Optional[Queue] = None)

Verifieer of de opstelling goed is. Dit wordt gedaan door de gemiddelde waarde van de referentie data te vergelijken met de gemiddelde waarde van de meting.

Parameters:

q – De queue waar het resultaat (bool) in wordt gestopt.

Returns:

None

measurement_start()

Start de meting frame om het herhaalbaar te maken

measurement(q=None)

Start de meting in een aparte thread en stop de resultaten in een queue.

Parameters:

q (Queue) – De queue waar de resultaten in worden gestopt.

Returns:

None

result_analysis(result: <Mock name='mock.ndarray' id='140056477809616'>)

Analyseer het resultaat van de meting en geef het resultaat weer

Parameters:

result (np.ndarray) – De data van de meting uit de queue.

Returns:

None

initialise_config_data() None

Initialiseer de data uit de config file en koppel deze aan de juiste attributen.

Returns:

None

write_to_txt(array: <Mock name='mock.ndarray' id='140056477809616'>)

Sla de meest recente meting op in een txt bestand met de naam MeestRecenteMeting.txt zodat deze altijd op te vragen is door de GUI of voor referentie metingen.

Parameters:

array (np.ndarray) – op te slaan data, numpy array met 2 kolommen (tijd, voltage)

Returns:

None

stop_measurement()

Zorg ervoor dat alle metingen stoppen en sluit de GUI af.

Returns:

None