{"kind":"Article","sha256":"efdc9513949986b9c5b789f78c190d52cf80d9b4b255f63f4ef0d680bbb32cfa","slug":"qcontrol3","location":"/appendix/qcontrol3.md","dependencies":[],"frontmatter":{"title":"QControl3, our python based experiment program","short_title":"QControl3","subtitle":"Introduction to QControl and explanation of the development choices we have made","numbering":{"heading_1":{"enabled":true},"heading_2":{"enabled":true}},"thumbnail":"/~gondret/phd_manuscript/build/gui_scan_controller-1b968ab8ed929d258209b589c6e0f8f4.png","content_includes_title":false,"authors":[{"nameParsed":{"literal":"Victor Gondret","given":"Victor","family":"Gondret"},"name":"Victor Gondret","orcid":"0009-0005-8468-161X","email":"victor.gondret@normalesup.org","affiliations":["Université Paris-Saclay, CNRS"],"url":"http://www.normalesup.org/~gondret/","id":"contributors-myst-generated-uid-0","corresponding":true}],"license":{"content":{"id":"CC-BY-NC-SA-4.0","name":"Creative Commons Attribution Non Commercial Share Alike 4.0 International","CC":true,"url":"https://creativecommons.org/licenses/by-nc-sa/4.0/"}},"github":"https://github.com/QuantumVictor","keywords":[],"affiliations":[{"id":"Université Paris-Saclay, CNRS","name":"Université Paris-Saclay, CNRS"}],"abbreviations":{"MOT":"Magneto-Optical Trap","BEC":"Bose-Einstein Condensate","MCP":"Micro-Channel Plate","DCE":"Dynamical Casimir Effect","HBT":"Hanbury-Brown and Twiss","CFD":"Constant Fraction Discriminator","TDC":"Time-to-Digital Converter","FPGA":"Field Programmable Gate Array","AOM":"Acousto-Optics Modulator","RF":"Radio-frequency","ODT":"Optical Dipole Trap","IGBT":"Insulated-Gap Bipolar Transistor","MPQ":"Max Planck Institute of Quantum Optics","PPT":"Positive Partial Transpose","SSR":"SuperSelection Rule","LN":"Logarithmic Negativity","UV":"UltraViolet","TOF":"Time-Of-Flight","TF":"Thomas-Fermi","CMB":"Cosmic Background Radiation"},"settings":{"myst_to_tex":{"codeStyle":"minted"}},"thumbnailOptimized":"/~gondret/phd_manuscript/build/gui_scan_controller-1b968ab8ed929d258209b589c6e0f8f4.webp","exports":[{"format":"md","filename":"qcontrol3.md","url":"/~gondret/phd_manuscript/build/qcontrol3-1eace5287d689088175387a408a41622.md"}]},"mdast":{"type":"root","children":[{"type":"block","position":{"start":{"line":14,"column":1},"end":{"line":14,"column":1}},"children":[{"type":"paragraph","position":{"start":{"line":16,"column":1},"end":{"line":18,"column":1}},"children":[{"type":"text","value":"Before spring 2021, the experiment was controlled with a homemade hardware, interfaced with Matlab but the materials was suspected to be\nfailing hence it was decided to replace it. The choice was made to use the Adwin Pro 2 hardware with a python wrapper QControl3 developed by the ","key":"HdYcEcomhd"},{"type":"abbreviation","title":"Max Planck Institute of Quantum Optics","children":[{"type":"text","value":"MPQ","key":"znAXZgUyU3"}],"key":"J1JRyCUUYA"},{"type":"text","value":" researchers Christoph Gohle, ","key":"dUVbTWa1Qw"},{"type":"link","url":"https://ultracold.sr/","position":{"start":{"line":16,"column":1},"end":{"line":16,"column":1}},"children":[{"type":"text","value":"Sebastian Blatt","position":{"start":{"line":16,"column":1},"end":{"line":16,"column":1}},"key":"e1qSdy636i"}],"urlSource":"https://ultracold.sr/","key":"zMp608TUt8"},{"type":"text","value":" and ","position":{"start":{"line":16,"column":1},"end":{"line":16,"column":1}},"key":"M873ObUWyR"},{"type":"link","url":"https://uni-tuebingen.de/en/fakultaeten/mathematisch-naturwissenschaftliche-fakultaet/fachbereiche/physik/institute/physikalisches-institut/bereiche/atomphysikquantenoptik/quantum-many-body-physics/","position":{"start":{"line":16,"column":1},"end":{"line":16,"column":1}},"children":[{"type":"text","value":"Christian Groß","position":{"start":{"line":16,"column":1},"end":{"line":16,"column":1}},"key":"pvMlo97G9u"}],"urlSource":"https://uni-tuebingen.de/en/fakultaeten/mathematisch-naturwissenschaftliche-fakultaet/fachbereiche/physik/institute/physikalisches-institut/bereiche/atomphysikquantenoptik/quantum-many-body-physics/","key":"Wt3J5k93fK"},{"type":"text","value":".\nThis python wrapper was imported by Marc Cheneau in the group who uses it on the ","position":{"start":{"line":16,"column":1},"end":{"line":16,"column":1}},"key":"IAXlyvaoeD"},{"type":"link","url":"https://www.lcf.institutoptique.fr/groupes-de-recherche/gaz-quantiques/experiences/dynamique-quantique","position":{"start":{"line":16,"column":1},"end":{"line":16,"column":1}},"children":[{"type":"text","value":"LCF Strontium experiment","position":{"start":{"line":16,"column":1},"end":{"line":16,"column":1}},"key":"tafi7KsWJ0"}],"urlSource":"https://www.lcf.institutoptique.fr/groupes-de-recherche/gaz-quantiques/experiences/dynamique-quantique","key":"h1MxScJYAM"},{"type":"text","value":".","position":{"start":{"line":16,"column":1},"end":{"line":16,"column":1}},"key":"QnH7RmsSgG"}],"key":"rNlOAx2pCA"},{"type":"paragraph","position":{"start":{"line":20,"column":1},"end":{"line":20,"column":1}},"children":[{"type":"text","value":"Note that this section does not intend to explain how QControl and the sequencer are interfaced and communicate : this can be found in ","position":{"start":{"line":20,"column":1},"end":{"line":20,"column":1}},"key":"unxICfssAe"},{"type":"cite","identifier":"raven_new_2022","label":"raven_new_2022","kind":"narrative","position":{"start":{"line":20,"column":136},"end":{"line":20,"column":151}},"children":[{"type":"text","value":"Raven (2022)","key":"wgMwWPrL9U"}],"enumerator":"1","key":"OQ9awrM24v"},{"type":"text","value":". This note is rather meant to introduce QControl3 through an installation guide and a user-guide for the next PhD students on the experiment (or other experiments).","position":{"start":{"line":20,"column":1},"end":{"line":20,"column":1}},"key":"bzwpLcQr8S"}],"key":"x3RYWbiCM7"},{"type":"paragraph","position":{"start":{"line":22,"column":1},"end":{"line":22,"column":1}},"children":[{"type":"text","value":"The ","position":{"start":{"line":22,"column":1},"end":{"line":22,"column":1}},"key":"rolCEVm0Hd"},{"type":"crossReference","position":{"start":{"line":22,"column":1},"end":{"line":22,"column":1}},"children":[{"type":"text","value":"first section","position":{"start":{"line":22,"column":1},"end":{"line":22,"column":1}},"key":"R8W7tJtUew"}],"identifier":"adwin_to_qc3","label":"adwin_to_qc3","kind":"heading","template":"Section %s","enumerator":"1","resolved":true,"html_id":"adwin-to-qc3","key":"RIvsX2padW"},{"type":"text","value":" explains why we chose to use the Adwin and QControl and gives a really short introduction of the sequencer features and its hardware configuration. The ","position":{"start":{"line":22,"column":1},"end":{"line":22,"column":1}},"key":"WfQzSsugS6"},{"type":"crossReference","position":{"start":{"line":22,"column":1},"end":{"line":22,"column":1}},"children":[{"type":"text","value":"second part","position":{"start":{"line":22,"column":1},"end":{"line":22,"column":1}},"key":"DhfMM4cEaS"}],"identifier":"intro_to_qc3","label":"intro_to_qc3","kind":"heading","template":"Section %s","enumerator":"2","resolved":true,"html_id":"intro-to-qc3","key":"GlEqTSwUg1"},{"type":"text","value":" is intended to be a tutorial on how to write a very simple script with QControl, introducing important concepts : this can be of interest if one wants to install QControl3 on its experiment. The ","position":{"start":{"line":22,"column":1},"end":{"line":22,"column":1}},"key":"VeFP7jXUOs"},{"type":"crossReference","position":{"start":{"line":22,"column":1},"end":{"line":22,"column":1}},"children":[{"type":"text","value":"third one","position":{"start":{"line":22,"column":1},"end":{"line":22,"column":1}},"key":"FzQhgs0ZnL"}],"identifier":"section-remote","label":"section-remote","kind":"heading","template":"Section %s","enumerator":"3","resolved":true,"html_id":"section-remote","key":"GPoiqgdnBf"},{"type":"text","value":" focuses on the ","position":{"start":{"line":22,"column":1},"end":{"line":22,"column":1}},"key":"zpeAsXpcFz"},{"type":"emphasis","position":{"start":{"line":22,"column":1},"end":{"line":22,"column":1}},"children":[{"type":"text","value":"remote drivers","position":{"start":{"line":22,"column":1},"end":{"line":22,"column":1}},"key":"yDv9LtjEwQ"}],"key":"H1ZaYjp11z"},{"type":"text","value":" that allows one to code additional devices (arbitrary function generators for example, cameras etc..) and explains how to code a really simple (and useless for the one presented) remote driver. Finally, the ","position":{"start":{"line":22,"column":1},"end":{"line":22,"column":1}},"key":"sot57WWFyB"},{"type":"crossReference","position":{"start":{"line":22,"column":1},"end":{"line":22,"column":1}},"children":[{"type":"text","value":"fourth part","position":{"start":{"line":22,"column":1},"end":{"line":22,"column":1}},"key":"RFS0MwS7aI"}],"identifier":"our-current-config","label":"our-current-config","kind":"heading","template":"Section %s","enumerator":"4","resolved":true,"html_id":"our-current-config","key":"oz9V6kXCiY"},{"type":"text","value":" describes how we coded our sequence and the choices we made for the scripts.","position":{"start":{"line":22,"column":1},"end":{"line":22,"column":1}},"key":"grlXSdc4rM"}],"key":"ieb7lLeDKw"}],"data":{"part":"abstract"},"key":"GPfDpQ8qgE"},{"type":"block","position":{"start":{"line":24,"column":1},"end":{"line":24,"column":1}},"children":[{"type":"heading","depth":2,"position":{"start":{"line":29,"column":1},"end":{"line":29,"column":1}},"children":[{"type":"text","value":"From Adwin to QControl3","position":{"start":{"line":29,"column":1},"end":{"line":29,"column":1}},"key":"fppvlOIpB1"}],"identifier":"adwin_to_qc3","label":"adwin_to_qc3","html_id":"adwin-to-qc3","enumerator":"1","key":"QNAFeqzRkH"},{"type":"heading","depth":3,"position":{"start":{"line":30,"column":1},"end":{"line":30,"column":1}},"children":[{"type":"text","value":"Change motivation : Adwin & QControl","position":{"start":{"line":30,"column":1},"end":{"line":30,"column":1}},"key":"QtoKzSM349"}],"identifier":"change-motivation-adwin-qcontrol","label":"Change motivation : Adwin & QControl","html_id":"change-motivation-adwin-qcontrol","implicit":true,"key":"dN5W9CfVN0"},{"type":"paragraph","position":{"start":{"line":31,"column":1},"end":{"line":33,"column":1}},"children":[{"type":"text","value":"The choice to use the ","position":{"start":{"line":31,"column":1},"end":{"line":31,"column":1}},"key":"oGaxfGidxH"},{"type":"link","url":"https://www.adwin.de/us/produkte/proII.html","position":{"start":{"line":31,"column":1},"end":{"line":31,"column":1}},"children":[{"type":"text","value":"ADwin-Pro II","position":{"start":{"line":31,"column":1},"end":{"line":31,"column":1}},"key":"K7jtzEBCqd"}],"urlSource":"https://www.adwin.de/us/produkte/proII.html","key":"WxEBYSrD0B"},{"type":"text","value":" system was made on the 1st February, 2021 in a meeting during which we decided to stop to persist on trying to run the experiment on its current configuration. On the “to-change” list, in addition to the sequencer, were also the cooling laser, the magnetic trap coils, the transverse molasses, the current power supply as well as possibly the ","key":"KwP4oxgaFy"},{"type":"abbreviation","title":"Magneto-Optical Trap","children":[{"type":"text","value":"MOT","key":"BUvwjK3JL2"}],"key":"Hzy6CNNmm9"},{"type":"text","value":" beams. In the ","key":"P3OtL1guYZ"},{"type":"link","url":"https://www.lcf.institutoptique.fr/groupes/gaz-quantiques","position":{"start":{"line":31,"column":1},"end":{"line":31,"column":1}},"children":[{"type":"text","value":"LCF Quantum Gases group","position":{"start":{"line":31,"column":1},"end":{"line":31,"column":1}},"key":"dw8ky07HXC"}],"urlSource":"https://www.lcf.institutoptique.fr/groupes/gaz-quantiques","key":"srRSKEEgFa"},{"type":"text","value":", all teams except the  ","position":{"start":{"line":31,"column":1},"end":{"line":31,"column":1}},"key":"iaKHcQF4id"},{"type":"link","url":"https://www.lcf.institutoptique.fr/groupes-de-recherche/gaz-quantiques/experiences/dynamique-quantique","position":{"start":{"line":31,"column":1},"end":{"line":31,"column":1}},"children":[{"type":"text","value":"Quantum Dynamics","position":{"start":{"line":31,"column":1},"end":{"line":31,"column":1}},"key":"Gr4Vr2o33M"}],"urlSource":"https://www.lcf.institutoptique.fr/groupes-de-recherche/gaz-quantiques/experiences/dynamique-quantique","key":"wO878eerVk"},{"type":"text","value":" use the National Instrument material together with ","position":{"start":{"line":31,"column":1},"end":{"line":31,"column":1}},"key":"YDqwjCNnt7"},{"type":"link","url":"https://akeshet.github.io/Cicero-Word-Generator/","position":{"start":{"line":31,"column":1},"end":{"line":31,"column":1}},"children":[{"type":"text","value":"Cicero","position":{"start":{"line":31,"column":1},"end":{"line":31,"column":1}},"key":"WyrBbhLeLB"}],"urlSource":"https://akeshet.github.io/Cicero-Word-Generator/","key":"w75BWjtC6x"},{"type":"footnoteReference","identifier":"ciceroisa","label":"ciceroisa","position":{"start":{"line":31,"column":1},"end":{"line":31,"column":1}},"number":1,"enumerator":"1","key":"y3gjykJlLd"},{"type":"text","value":" developed by ","position":{"start":{"line":31,"column":1},"end":{"line":31,"column":1}},"key":"bOww2hm80D"},{"type":"cite","identifier":"keshet_distributed_2013","label":"keshet_distributed_2013","kind":"narrative","position":{"start":{"line":31,"column":810},"end":{"line":31,"column":834}},"children":[{"type":"text","value":"Keshet & Ketterle (2013)","key":"seDPc3iiTC"}],"enumerator":"2","key":"du2ClGT0vb"},{"type":"text","value":". The advantage of the Adwin material was its availability : Marc had one additional sequencer in spare and proposed us to test it. Considering the other changes were also expansive, we decided to stay with this material and to save money for other investments","position":{"start":{"line":31,"column":1},"end":{"line":31,"column":1}},"key":"fKOf8JgM8s"},{"type":"footnoteReference","identifier":"thanks-marc","label":"thanks-marc","position":{"start":{"line":31,"column":1},"end":{"line":31,"column":1}},"number":3,"enumerator":"3","key":"fUgS9V64ry"},{"type":"text","value":". ","position":{"start":{"line":31,"column":1},"end":{"line":31,"column":1}},"key":"Zq9PbMCsqt"},{"type":"break","position":{"start":{"line":31,"column":1},"end":{"line":31,"column":1}},"key":"RQJPVmkNBx"},{"type":"text","value":"Of course, the hardware material does not impose to work with the QControl software: to my knowledge, ","position":{"start":{"line":31,"column":1},"end":{"line":31,"column":1}},"key":"BrW9nzEqPq"},{"type":"link","url":"http://www-lpl.univ-paris13.fr/bec/Sodium/Index.htm","position":{"start":{"line":31,"column":1},"end":{"line":31,"column":1}},"children":[{"type":"text","value":"the Sodium experiment at the Laboratoire de Physique des Lasers","position":{"start":{"line":31,"column":1},"end":{"line":31,"column":1}},"key":"xS7tpAOZ5F"}],"urlSource":"http://www-lpl.univ-paris13.fr/bec/Sodium/Index.htm","key":"IgSSFpBZGj"},{"type":"text","value":" uses also the Adwin-Pro II material but together with a Matlab wrapper developed by Aurélien Perrin. The Adwin material is also used in Wien","position":{"start":{"line":31,"column":1},"end":{"line":31,"column":1}},"key":"FPf8LuvrnZ"},{"type":"footnoteReference","identifier":"wien-group","label":"wien-group","position":{"start":{"line":31,"column":1},"end":{"line":31,"column":1}},"number":4,"enumerator":"4","key":"rp6nlAHGZd"},{"type":"text","value":" together with the ","position":{"start":{"line":31,"column":1},"end":{"line":31,"column":1}},"key":"NRX6K2ALjo"},{"type":"link","url":"https://docs.labscriptsuite.org/en/latest/","position":{"start":{"line":31,"column":1},"end":{"line":31,"column":1}},"children":[{"type":"text","value":"Labscript","position":{"start":{"line":31,"column":1},"end":{"line":31,"column":1}},"key":"apLlmDGxQD"}],"urlSource":"https://docs.labscriptsuite.org/en/latest/","key":"pnj4G2UOYf"},{"type":"text","value":" program developed by ","position":{"start":{"line":31,"column":1},"end":{"line":31,"column":1}},"key":"KcxOGUVacB"},{"type":"cite","identifier":"starkey_scripted_2013","label":"starkey_scripted_2013","kind":"narrative","position":{"start":{"line":31,"column":1582},"end":{"line":31,"column":1604}},"children":[{"type":"text","value":"Starkey ","key":"F6u1B6AZ8J"},{"type":"emphasis","children":[{"type":"text","value":"et al.","key":"BNo7pM8Ydq"}],"key":"HUBkC8mPuc"},{"type":"text","value":" (2013)","key":"QA7kFgYhjq"}],"enumerator":"3","key":"C04KmIQZbD"},{"type":"text","value":".  In a quantum optics experiment, the Adwin-Pro II material was also used to perform ","position":{"start":{"line":31,"column":1},"end":{"line":31,"column":1}},"key":"LBuE97Ev6E"},{"type":"emphasis","position":{"start":{"line":31,"column":1},"end":{"line":31,"column":1}},"children":[{"type":"text","value":"real-time quantum feedback to prepares and stabilize photon number states","position":{"start":{"line":31,"column":1},"end":{"line":31,"column":1}},"key":"l00RgztAau"}],"key":"SzsDJgCEyG"},{"type":"text","value":" by ","position":{"start":{"line":31,"column":1},"end":{"line":31,"column":1}},"key":"XgdbeAnfMc"},{"type":"cite","identifier":"sayrin_real_time_2011","label":"sayrin_real_time_2011","kind":"narrative","position":{"start":{"line":31,"column":1769},"end":{"line":31,"column":1791}},"children":[{"type":"text","value":"Sayrin ","key":"oRaYrZRJl3"},{"type":"emphasis","children":[{"type":"text","value":"et al.","key":"migr7nWVJU"}],"key":"abHKF8u2x3"},{"type":"text","value":" (2011)","key":"QlVw7bZAio"}],"enumerator":"4","key":"GK3cujNcns"},{"type":"text","value":". It was distributed more recently as a python package ","position":{"start":{"line":31,"column":1},"end":{"line":31,"column":1}},"key":"U8ToGlIqc3"},{"type":"link","url":"https://pypi.org/project/nqontrol/","position":{"start":{"line":31,"column":1},"end":{"line":31,"column":1}},"children":[{"type":"text","value":"NQontrol","position":{"start":{"line":31,"column":1},"end":{"line":31,"column":1}},"key":"Kbgoh02MB4"}],"urlSource":"https://pypi.org/project/nqontrol/","key":"r2v2JumKeh"},{"type":"text","value":" by ","position":{"start":{"line":31,"column":1},"end":{"line":31,"column":1}},"key":"MjCnuAzI3q"},{"type":"cite","identifier":"darsow_fromm_nqontrol_2020","label":"darsow_fromm_nqontrol_2020","kind":"narrative","position":{"start":{"line":31,"column":1896},"end":{"line":31,"column":1923}},"children":[{"type":"text","value":"Darsow-Fromm ","key":"qcOn6yHWvS"},{"type":"emphasis","children":[{"type":"text","value":"et al.","key":"zgUEx8mYvf"}],"key":"sMK7P0Xq9F"},{"type":"text","value":" (2020)","key":"WtiDMCKeMy"}],"enumerator":"5","key":"oLjNdQlOD9"},{"type":"text","value":" ","position":{"start":{"line":31,"column":1},"end":{"line":31,"column":1}},"key":"kQTfTo9mRl"},{"type":"break","position":{"start":{"line":31,"column":1},"end":{"line":31,"column":1}},"key":"b10bzXyn0O"},{"type":"text","value":"Nevertheless, working with QControl3 seemed the best option as the LCF strontium team was working with this wrapper and we could benefit from Marc experience. With hindsight, the criticism I would address to QControl3 would be the non-free online access to the code","position":{"start":{"line":31,"column":1},"end":{"line":31,"column":1}},"key":"Qg90hZOEM7"},{"type":"footnoteReference","identifier":"access-online","label":"access-online","position":{"start":{"line":31,"column":1},"end":{"line":31,"column":1}},"number":8,"enumerator":"8","key":"bZppxb76Zu"},{"type":"text","value":" making the collaboration to this project not trivial. The documentation is not yet complete even though I will try to make a contribution based on this note.","position":{"start":{"line":31,"column":1},"end":{"line":31,"column":1}},"key":"tmjNDy9PN6"}],"key":"Nwbg3qmjz4"},{"type":"comment","value":"QControl being a more recent project compare to other , all possibilities offered by the Adwin-Pro II are not","position":{"start":{"line":34,"column":1},"end":{"line":34,"column":1}},"key":"iVUustaK7L"},{"type":"heading","depth":3,"position":{"start":{"line":44,"column":1},"end":{"line":44,"column":1}},"children":[{"type":"text","value":"Adwin Pro-II features","position":{"start":{"line":44,"column":1},"end":{"line":44,"column":1}},"key":"Mrp54wp3jx"}],"identifier":"adwin-pro-ii-features","label":"Adwin Pro-II features","html_id":"adwin-pro-ii-features","implicit":true,"key":"Ro4TcGe1M4"},{"type":"paragraph","position":{"start":{"line":45,"column":1},"end":{"line":46,"column":1}},"children":[{"type":"text","value":"We use the ADwin-Pro II system with a processor module T12 that “provides high performance using 1 GHz clock rate, 1 GB memory, and a 64-bit FPU (double precision) for float calculations” according to the\n","position":{"start":{"line":45,"column":1},"end":{"line":45,"column":1}},"key":"wiJWixWykj"},{"type":"link","url":"https://www.adwin.de/us/produkte/proII.html","position":{"start":{"line":45,"column":1},"end":{"line":45,"column":1}},"children":[{"type":"text","value":"Adwin documentation","position":{"start":{"line":45,"column":1},"end":{"line":45,"column":1}},"key":"onGdbZ2wbR"}],"urlSource":"https://www.adwin.de/us/produkte/proII.html","key":"ro6LYNmK8G"},{"type":"text","value":". Beside this “heart” module, we currently have two other types of cards that perform analog and digital signals. Analog outputs modules, ","position":{"start":{"line":45,"column":1},"end":{"line":45,"column":1}},"key":"FhzTyTD2gG"},{"type":"emphasis","position":{"start":{"line":45,"column":1},"end":{"line":45,"column":1}},"children":[{"type":"text","value":"Pro II AOut-8/16","position":{"start":{"line":45,"column":1},"end":{"line":45,"column":1}},"key":"p5iNYl1F6k"}],"key":"xNorYTPKPJ"},{"type":"text","value":", have 8 channels with 16 bit resolution, a voltage range of ","position":{"start":{"line":45,"column":1},"end":{"line":45,"column":1}},"key":"SJUHRLAoo6"},{"type":"inlineMath","value":"\\pm 10","position":{"start":{"line":45,"column":1},"end":{"line":45,"column":1}},"html":"<span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mo>±</mo><mn>10</mn></mrow><annotation encoding=\"application/x-tex\">\\pm 10</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:0.7278em;vertical-align:-0.0833em;\"></span><span class=\"mord\">±</span><span class=\"mord\">10</span></span></span></span>","key":"rtrghcmS6I"},{"type":"text","value":" V and a settling time of 3 s. Digital output modules ","position":{"start":{"line":45,"column":1},"end":{"line":45,"column":1}},"key":"Sj2nA8fQPV"},{"type":"emphasis","position":{"start":{"line":45,"column":1},"end":{"line":45,"column":1}},"children":[{"type":"text","value":"DIO-32","position":{"start":{"line":45,"column":1},"end":{"line":45,"column":1}},"key":"sfIEA6HGIH"}],"key":"koZTg0PXUj"},{"type":"text","value":" composed of 32 TTL channels with edge output of 100 MHz with time stamp. Even thought the value of 100 MHz seems to allow a minimum pulse duration of 10 ns, the minimum value allowed by QControl3 is 5 µs.","position":{"start":{"line":45,"column":1},"end":{"line":45,"column":1}},"key":"ejzFtkgt69"}],"key":"hDYYnD5mND"},{"type":"comment","value":"FIXME\\\nTODO : add a photo showing the device.\\\nTODO : add MIO4 card and RTD8 card","position":{"start":{"line":47,"column":1},"end":{"line":49,"column":1}},"key":"cdYFD9n7Ml"},{"type":"heading","depth":3,"position":{"start":{"line":52,"column":1},"end":{"line":52,"column":1}},"children":[{"type":"text","value":"Adwin Pro-II hardware configuration","position":{"start":{"line":52,"column":1},"end":{"line":52,"column":1}},"key":"qTtoXMnspB"}],"identifier":"subsection-adwin-hardware-config","label":"subsection-adwin-hardware-config","html_id":"subsection-adwin-hardware-config","key":"q8wOcg2YKp"},{"type":"paragraph","position":{"start":{"line":54,"column":1},"end":{"line":54,"column":1}},"children":[{"type":"text","value":"The following section resume the Adwin Pro-II material configuration that is needed to use it with QControl3 on a Linux based computer. First, the ","position":{"start":{"line":54,"column":1},"end":{"line":54,"column":1}},"key":"XhbhONXMfT"},{"type":"link","url":"https://www.adwin.de/us/download/linux.html","position":{"start":{"line":54,"column":1},"end":{"line":54,"column":1}},"children":[{"type":"text","value":"Adwin driver","position":{"start":{"line":54,"column":1},"end":{"line":54,"column":1}},"key":"D5Iccch7I8"}],"urlSource":"https://www.adwin.de/us/download/linux.html","key":"OK0jIDxVgZ"},{"type":"text","value":" must be installed - the 5th driver and not the most recent one - following the documentation. Once the connection with the sequencer is established, a fixed (local) IP address should be set to the device and then saved into a driver property file, using the ","position":{"start":{"line":54,"column":1},"end":{"line":54,"column":1}},"key":"ExFONa3BRl"},{"type":"inlineCode","value":"adconfig add","position":{"start":{"line":54,"column":1},"end":{"line":54,"column":1}},"key":"iWrvdZVzIO"},{"type":"text","value":" command.","position":{"start":{"line":54,"column":1},"end":{"line":54,"column":1}},"key":"CijR5HqkIB"}],"key":"hLfwjYEAkw"},{"type":"code","lang":"shell","value":"$ adconfig config 00:22:71:03:08:F8 IP 192.168.1.4  MASK 255.255.255.00\n$ adconfig add 0x001 TYPE net IP 192.168.1.4","key":"i1lEthWgtJ"},{"type":"paragraph","position":{"start":{"line":61,"column":1},"end":{"line":61,"column":1}},"children":[{"type":"text","value":"One must then ","position":{"start":{"line":61,"column":1},"end":{"line":61,"column":1}},"key":"cccA1bhTmf"},{"type":"emphasis","position":{"start":{"line":61,"column":1},"end":{"line":61,"column":1}},"children":[{"type":"text","value":"declare","position":{"start":{"line":61,"column":1},"end":{"line":61,"column":1}},"key":"Il993uiNpe"}],"key":"jf58mHwZYQ"},{"type":"text","value":" the number and the address of each card using the ADPro software, only available on a Windows. Note that the minimal configuration for QControl3 to work is with one DIO-32 card. To choose the number and the address of each card, one should respect the ","position":{"start":{"line":61,"column":1},"end":{"line":61,"column":1}},"key":"zTzd80bLhI"},{"type":"crossReference","position":{"start":{"line":61,"column":1},"end":{"line":61,"column":1}},"children":[{"type":"text","value":"Table ","key":"esa7kT8wAM"},{"type":"text","value":"1","key":"RQ8PGxy4Bv"}],"identifier":"table-cards-adwin","label":"table-cards-adwin","kind":"table","template":"Table %s","enumerator":"1","resolved":true,"html_id":"table-cards-adwin","key":"KXiElcIKNX"},{"type":"text","value":" ","position":{"start":{"line":61,"column":1},"end":{"line":61,"column":1}},"key":"w50UaOEwJx"},{"type":"link","url":"https://gitlab.in2p3.fr/gaz-quantiques-lcf/helium-1/qcontrol3_driver_timing_adwin/-/blob/master/qcontrol3/driver/timing/adwin/qc3-firmware/README.md","position":{"start":{"line":61,"column":1},"end":{"line":61,"column":1}},"children":[{"type":"text","value":"conventions","position":{"start":{"line":61,"column":1},"end":{"line":61,"column":1}},"key":"N7d7AU0sYk"}],"urlSource":"https://gitlab.in2p3.fr/gaz-quantiques-lcf/helium-1/qcontrol3_driver_timing_adwin/-/blob/master/qcontrol3/driver/timing/adwin/qc3-firmware/README.md","key":"GAaTnFJnkC"},{"type":"text","value":". Note also that one could use ADpro to control the outputs of the cards to check the hardware output signals.","position":{"start":{"line":61,"column":1},"end":{"line":61,"column":1}},"key":"xrGkC3okUL"}],"key":"gJixATEUjE"},{"type":"container","kind":"table","identifier":"table-cards-adwin","label":"table-cards-adwin","children":[{"type":"caption","children":[{"type":"paragraph","position":{"start":{"line":67,"column":1},"end":{"line":67,"column":1}},"children":[{"type":"captionNumber","kind":"table","label":"table-cards-adwin","identifier":"table-cards-adwin","html_id":"table-cards-adwin","enumerator":"1","children":[{"type":"text","value":"Table ","key":"GiXBdHljHr"},{"type":"text","value":"1","key":"djCKx9OYD1"},{"type":"text","value":":","key":"wBLhcMGiV3"}],"template":"Table %s:","key":"Y3zhbBjgVw"},{"type":"text","value":"Adwin cards available wit QControl and their authorized address range. Lecture : to run QControl with Adwin material, one must use at least 1 and less than 4 digital cards and set their address number between 1 to 4. It is possible to use also a RTD8 card","position":{"start":{"line":67,"column":1},"end":{"line":67,"column":1}},"key":"RG91LEGHPx"}],"key":"DCkgstnVSS"}],"key":"hIzpxL1mbQ"},{"type":"table","position":{"start":{"line":68,"column":1},"end":{"line":73,"column":1}},"children":[{"type":"tableRow","position":{"start":{"line":68,"column":1},"end":{"line":68,"column":1}},"children":[{"type":"tableCell","header":true,"align":"left","position":{"start":{"line":68,"column":1},"end":{"line":68,"column":1}},"children":[{"type":"text","value":"Card name","position":{"start":{"line":68,"column":1},"end":{"line":68,"column":1}},"key":"kamVpX3ilv"}],"key":"e0EHhxQqUu"},{"type":"tableCell","header":true,"align":"center","position":{"start":{"line":68,"column":1},"end":{"line":68,"column":1}},"children":[{"type":"text","value":"Number range","position":{"start":{"line":68,"column":1},"end":{"line":68,"column":1}},"key":"ZqXmyvF2Vm"}],"key":"pb144InOgB"},{"type":"tableCell","header":true,"align":"center","position":{"start":{"line":68,"column":1},"end":{"line":68,"column":1}},"children":[{"type":"text","value":"Address value range","position":{"start":{"line":68,"column":1},"end":{"line":68,"column":1}},"key":"fm94xemriT"}],"key":"dnjysG3D7m"}],"key":"gS7pLyPfPY"},{"type":"tableRow","position":{"start":{"line":70,"column":1},"end":{"line":70,"column":1}},"children":[{"type":"tableCell","align":"left","position":{"start":{"line":70,"column":1},"end":{"line":70,"column":1}},"children":[{"type":"text","value":"DIO-32","position":{"start":{"line":70,"column":1},"end":{"line":70,"column":1}},"key":"LofdtvPNyH"}],"key":"lQub9dckSP"},{"type":"tableCell","align":"center","position":{"start":{"line":70,"column":1},"end":{"line":70,"column":1}},"children":[{"type":"text","value":"1-4","position":{"start":{"line":70,"column":1},"end":{"line":70,"column":1}},"key":"fVi4g1EMcy"}],"key":"cxJtO1pmau"},{"type":"tableCell","align":"center","position":{"start":{"line":70,"column":1},"end":{"line":70,"column":1}},"children":[{"type":"text","value":"1-4","position":{"start":{"line":70,"column":1},"end":{"line":70,"column":1}},"key":"bJ6CC18a4r"}],"key":"nvPKBtFsGa"}],"key":"SYOKjFTZEJ"},{"type":"tableRow","position":{"start":{"line":71,"column":1},"end":{"line":71,"column":1}},"children":[{"type":"tableCell","align":"left","position":{"start":{"line":71,"column":1},"end":{"line":71,"column":1}},"children":[{"type":"text","value":"AOUT8/16","position":{"start":{"line":71,"column":1},"end":{"line":71,"column":1}},"key":"sN0FTQq4Ln"}],"key":"TodRiwWodE"},{"type":"tableCell","align":"center","position":{"start":{"line":71,"column":1},"end":{"line":71,"column":1}},"children":[{"type":"text","value":"0-6","position":{"start":{"line":71,"column":1},"end":{"line":71,"column":1}},"key":"splc5sypna"}],"key":"mHiW7HnfXG"},{"type":"tableCell","align":"center","position":{"start":{"line":71,"column":1},"end":{"line":71,"column":1}},"children":[{"type":"text","value":"5-10","position":{"start":{"line":71,"column":1},"end":{"line":71,"column":1}},"key":"EmoKR4eBNI"}],"key":"nKIiBV6Jio"}],"key":"jXU7JoG21V"},{"type":"tableRow","position":{"start":{"line":72,"column":1},"end":{"line":72,"column":1}},"children":[{"type":"tableCell","align":"left","position":{"start":{"line":72,"column":1},"end":{"line":72,"column":1}},"children":[{"type":"text","value":"MIO4","position":{"start":{"line":72,"column":1},"end":{"line":72,"column":1}},"key":"lQcrEqSiYX"}],"key":"lC4i69Z5Pz"},{"type":"tableCell","align":"center","position":{"start":{"line":72,"column":1},"end":{"line":72,"column":1}},"children":[{"type":"text","value":"0-1","position":{"start":{"line":72,"column":1},"end":{"line":72,"column":1}},"key":"OR6WQkHDWz"}],"key":"a0YjMwFqIj"},{"type":"tableCell","align":"center","position":{"start":{"line":72,"column":1},"end":{"line":72,"column":1}},"children":[{"type":"text","value":"14","position":{"start":{"line":72,"column":1},"end":{"line":72,"column":1}},"key":"ngXpnTSiUE"}],"key":"rE7vuDYbQq"}],"key":"tU7E33Ngwp"},{"type":"tableRow","position":{"start":{"line":73,"column":1},"end":{"line":73,"column":1}},"children":[{"type":"tableCell","align":"left","position":{"start":{"line":73,"column":1},"end":{"line":73,"column":1}},"children":[{"type":"text","value":"RTD8","position":{"start":{"line":73,"column":1},"end":{"line":73,"column":1}},"key":"xuy222Rzp1"}],"key":"oVkYnhUo2x"},{"type":"tableCell","align":"center","position":{"start":{"line":73,"column":1},"end":{"line":73,"column":1}},"children":[{"type":"text","value":"0-1","position":{"start":{"line":73,"column":1},"end":{"line":73,"column":1}},"key":"vSLYrJSx0W"}],"key":"gUl2xeUSce"},{"type":"tableCell","align":"center","position":{"start":{"line":73,"column":1},"end":{"line":73,"column":1}},"children":[{"type":"text","value":"15","position":{"start":{"line":73,"column":1},"end":{"line":73,"column":1}},"key":"a3Q9fjWawI"}],"key":"Xb61zvYsrj"}],"key":"yxdtoqm7cl"}],"key":"RmrZ1PfKAX"}],"enumerator":"1","html_id":"table-cards-adwin","key":"YrWWArNvYB"},{"type":"heading","depth":2,"position":{"start":{"line":80,"column":1},"end":{"line":80,"column":1}},"children":[{"type":"text","value":"Introduction to QControl3","position":{"start":{"line":80,"column":1},"end":{"line":80,"column":1}},"key":"V5PE2HHNY2"}],"identifier":"intro_to_qc3","label":"intro_to_qc3","html_id":"intro-to-qc3","enumerator":"2","key":"D7pj1n8hUN"},{"type":"paragraph","position":{"start":{"line":81,"column":1},"end":{"line":81,"column":1}},"children":[{"type":"text","value":"In this section, I will walk you through getting start with QControl3. The first subsection provides a guide on installing the various QControl packages on your computer, while the second introduces the declaration of different channels that will be used in scripts. The third subsection covers the client and the various commands associated with it, while the fourth outlines the structure of a simple script. In this part, we will focus on a single Timing Controller, meaning that only the sequencer channels will be accessible. Programming and using other Timing Controllers will be discussed in a ","position":{"start":{"line":81,"column":1},"end":{"line":81,"column":1}},"key":"Eb8eN9irao"},{"type":"crossReference","position":{"start":{"line":81,"column":1},"end":{"line":81,"column":1}},"children":[{"type":"text","value":"dedicated section","position":{"start":{"line":81,"column":1},"end":{"line":81,"column":1}},"key":"rxKqIuKF3q"}],"identifier":"section-remote","label":"section-remote","kind":"heading","template":"Section %s","enumerator":"3","resolved":true,"html_id":"section-remote","key":"b6Nvwn3vsW"},{"type":"text","value":".","position":{"start":{"line":81,"column":1},"end":{"line":81,"column":1}},"key":"TgvRl2HhvR"}],"key":"UaILSjnLbr"},{"type":"paragraph","position":{"start":{"line":83,"column":1},"end":{"line":83,"column":1}},"children":[{"type":"crossReference","position":{"start":{"line":83,"column":1},"end":{"line":83,"column":1}},"children":[{"type":"text","value":"Figure ","key":"a3mPkFSFBf"},{"type":"text","value":"1","key":"p6Qpk27hTC"}],"identifier":"qcontrol-timing-system","label":"qcontrol-timing-system","kind":"figure","template":"Figure %s","enumerator":"1","resolved":true,"html_id":"qcontrol-timing-system","key":"iJgElSNgY6"},{"type":"text","value":" summarizes the basic functionalities of QControl. The strength of the code lies in enabling multiple clocks to evolve in parallel once the ","position":{"start":{"line":83,"column":1},"end":{"line":83,"column":1}},"key":"lVduP7f5Ef"},{"type":"emphasis","position":{"start":{"line":83,"column":1},"end":{"line":83,"column":1}},"children":[{"type":"text","value":"starting signal","position":{"start":{"line":83,"column":1},"end":{"line":83,"column":1}},"key":"p3fUnSZFfc"}],"key":"X1vkOelKy3"},{"type":"text","value":" is given by the main clock. This can be particularly useful for using the same device twice during a sequence or for providing feedback within the same sequence. Any clock with independent timing is referred to as a ","position":{"start":{"line":83,"column":1},"end":{"line":83,"column":1}},"key":"phi09tOnyk"},{"type":"emphasis","position":{"start":{"line":83,"column":1},"end":{"line":83,"column":1}},"children":[{"type":"text","value":"Timing Controller","position":{"start":{"line":83,"column":1},"end":{"line":83,"column":1}},"key":"r56CRccgaf"}],"key":"eEFOnPuNQw"},{"type":"text","value":", and only one of them is the absolute master of time – in our case, it will, of course, be the sequencer. Each Timing Controller is a node in the ","position":{"start":{"line":83,"column":1},"end":{"line":83,"column":1}},"key":"Pz1wWxWRR4"},{"type":"emphasis","position":{"start":{"line":83,"column":1},"end":{"line":83,"column":1}},"children":[{"type":"text","value":"Timing System","position":{"start":{"line":83,"column":1},"end":{"line":83,"column":1}},"key":"h4BedwVuVr"}],"key":"OO2J4vaihI"},{"type":"text","value":" and can have various devices under it: the so-called ","position":{"start":{"line":83,"column":1},"end":{"line":83,"column":1}},"key":"kOUqqluXsn"},{"type":"emphasis","position":{"start":{"line":83,"column":1},"end":{"line":83,"column":1}},"children":[{"type":"text","value":"Timing Devices","position":{"start":{"line":83,"column":1},"end":{"line":83,"column":1}},"key":"lOhdCREg3I"}],"key":"R0YfPWc9pF"},{"type":"text","value":". For example, a current generator will be a Timing Device and a child of a Timing Controller, that can control several other devices. Below the Timing Device node, it will be necessary to create temporal channels so that the user can send instructions to the device (e.g., “current 2 A; output on”). Note that the words ","position":{"start":{"line":83,"column":1},"end":{"line":83,"column":1}},"key":"vmU2nfhQad"},{"type":"emphasis","position":{"start":{"line":83,"column":1},"end":{"line":83,"column":1}},"children":[{"type":"text","value":"timing","position":{"start":{"line":83,"column":1},"end":{"line":83,"column":1}},"key":"CJCWam3r06"}],"key":"cemIQbHgZq"},{"type":"text","value":" in front of each word is not only here to show off but to emphasize the fact that any action on a timing channels is done at a given time. For example, the instruction “output on” sent to the current generator will be sent at a given time of the sequence. The relationships between Timing Controller, Timing Device, and Timing Channel will be discussed in ","position":{"start":{"line":83,"column":1},"end":{"line":83,"column":1}},"key":"RZ0AdatPCJ"},{"type":"crossReference","position":{"start":{"line":83,"column":1},"end":{"line":83,"column":1}},"children":[{"type":"text","value":"the following section","position":{"start":{"line":83,"column":1},"end":{"line":83,"column":1}},"key":"uoeoIbsRHe"}],"identifier":"section-remote","label":"section-remote","kind":"heading","template":"Section %s","enumerator":"3","resolved":true,"html_id":"section-remote","key":"Bp2LGTHebu"},{"type":"text","value":". Here we will simply explain how to add a Timing Controller to our Timing System and then create user channels from existing timing channels.","position":{"start":{"line":83,"column":1},"end":{"line":83,"column":1}},"key":"mjYn9Ermjh"}],"key":"iHRWrj5vWZ"},{"type":"container","kind":"figure","identifier":"qcontrol-timing-system","label":"qcontrol-timing-system","children":[{"type":"image","url":"/~gondret/phd_manuscript/build/qc3_basic-a9327fad28a44504565576ce5c342dac.png","alt":"Scheme of the QControl3 timing system","width":"100%","align":"center","key":"aey10GmNKG","urlSource":"images/qc3_basic.png","urlOptimized":"/~gondret/phd_manuscript/build/qc3_basic-a9327fad28a44504565576ce5c342dac.webp"},{"type":"caption","children":[{"type":"paragraph","position":{"start":{"line":93,"column":1},"end":{"line":93,"column":1}},"children":[{"type":"captionNumber","kind":"figure","label":"qcontrol-timing-system","identifier":"qcontrol-timing-system","html_id":"qcontrol-timing-system","enumerator":"1","children":[{"type":"text","value":"Figure ","key":"pAdv1cD0C7"},{"type":"text","value":"1","key":"ul8MMAiFFl"},{"type":"text","value":":","key":"e4M64oD5M1"}],"template":"Figure %s:","key":"ixraRMrd2C"},{"type":"text","value":"QControl3 timing system. The user script is compiled and a sequence of events is passed to the Timing system composed of Timing Controller and Software Controller. The clock of each controller will evolve independently : Timing Controller time is set by the sequencer clock while Software Controller time will be set by the computer on which the remote runs. The sequencer timing is “strict” since it controls digital and analogue output up to the nanosecond scale while Software Controllers have more sloppy timings - typically some ten of ms. Programming devices during a run and not before able the use of the same device at two different time in the experiment in different configurations. For example, we use the same current generator to perform compensation magnetic fields during the optical molasses and for the magnetic compensation to maintain a bias during the optical dipole trap. An other example of the use of this soft timing is the trigger of the evaporative ","key":"HaPKItIdtJ"},{"type":"abbreviation","title":"Radio-frequency","children":[{"type":"text","value":"RF","key":"raNuRpV2yG"}],"key":"yc6bvNSuhe"},{"type":"text","value":" ramp that is trigger with a “Output On” command sent with a remote server at soft time. Double arrows between blocks mean that timing channels can also send back measured values to their timing controller : it is the case for example for a camera which returns the image, or an oscilloscope that returns the measured voltage. In principle, it is possible to register analog signal with inputs cards of the Adwin material but this was not yet implemented. © Inspired from M. Cheneau seminar.","key":"CSkkvEcTqX"}],"key":"M0DAu4chwp"}],"key":"APtHF17ds1"}],"enumerator":"1","html_id":"qcontrol-timing-system","key":"StRvbGnIxH"},{"type":"heading","depth":3,"position":{"start":{"line":97,"column":1},"end":{"line":97,"column":1}},"children":[{"type":"text","value":"Installation","position":{"start":{"line":97,"column":1},"end":{"line":97,"column":1}},"key":"vsHAlOiPLL"}],"identifier":"installation","label":"Installation","html_id":"installation","implicit":true,"key":"NXwdQ0tZTM"},{"type":"paragraph","position":{"start":{"line":98,"column":1},"end":{"line":98,"column":1}},"children":[{"type":"text","value":"The QControl3 programs can be downloaded from the ","position":{"start":{"line":98,"column":1},"end":{"line":98,"column":1}},"key":"JwFj99jNDD"},{"type":"link","url":"https://gitlab.mpcdf.mpg.de/qcontrol3","position":{"start":{"line":98,"column":1},"end":{"line":98,"column":1}},"children":[{"type":"text","value":"MPQ gitlab","position":{"start":{"line":98,"column":1},"end":{"line":98,"column":1}},"key":"yZVSzJScnd"}],"urlSource":"https://gitlab.mpcdf.mpg.de/qcontrol3","key":"kO40V7sSR7"},{"type":"text","value":" server or from the fork branch on our (public) ","position":{"start":{"line":98,"column":1},"end":{"line":98,"column":1}},"key":"X3KnBdC3CD"},{"type":"link","url":"https://gitlab.in2p3.fr/gaz-quantiques-lcf/helium-1","position":{"start":{"line":98,"column":1},"end":{"line":98,"column":1}},"children":[{"type":"text","value":"gitlab server","position":{"start":{"line":98,"column":1},"end":{"line":98,"column":1}},"key":"Jw05Ku1DSh"}],"urlSource":"https://gitlab.in2p3.fr/gaz-quantiques-lcf/helium-1","key":"yjslenuIpq"},{"type":"text","value":". Note that QControl was developed on Linux-based computers, but it seems that it was extended for Windows. In the following, I will assume that one works with Linux. Depending on the devices used in your experiment, a various number of packages can be needed, but we will focus here on the minimal configuration in order to run the simplest sequence possible. The first step is to create a ","position":{"start":{"line":98,"column":1},"end":{"line":98,"column":1}},"key":"la14fAUbpB"},{"type":"link","url":"https://realpython.com/python-virtual-environments-a-primer/","position":{"start":{"line":98,"column":1},"end":{"line":98,"column":1}},"children":[{"type":"text","value":"virtual environment","position":{"start":{"line":98,"column":1},"end":{"line":98,"column":1}},"key":"j4gNAY4Cg5"}],"urlSource":"https://realpython.com/python-virtual-environments-a-primer/","key":"wjpiXX28Kb"},{"type":"text","value":" so that QControl3 is not installed on your python’s system distribution. In the following, any installation will be done within the qc3 virtual environment, even if it is not specified. There are four essential packages needed to use QControl3.","position":{"start":{"line":98,"column":1},"end":{"line":98,"column":1}},"key":"eeeeEJG2nm"}],"key":"stqboWcPeg"},{"type":"list","ordered":false,"spread":false,"position":{"start":{"line":100,"column":1},"end":{"line":104,"column":1}},"children":[{"type":"listItem","spread":true,"position":{"start":{"line":100,"column":1},"end":{"line":100,"column":1}},"children":[{"type":"link","url":"https://gitlab.in2p3.fr/gaz-quantiques-lcf/helium-1/qunits","position":{"start":{"line":100,"column":1},"end":{"line":100,"column":1}},"children":[{"type":"inlineCode","value":"qunits","position":{"start":{"line":100,"column":1},"end":{"line":100,"column":1}},"key":"lyytDxT3ls"}],"urlSource":"https://gitlab.in2p3.fr/gaz-quantiques-lcf/helium-1/qunits","key":"ArYOkxWTqd"},{"type":"text","value":" is used by all other packages and hence ","position":{"start":{"line":100,"column":1},"end":{"line":100,"column":1}},"key":"QFIu5TuQRM"},{"type":"strong","position":{"start":{"line":100,"column":1},"end":{"line":100,"column":1}},"children":[{"type":"text","value":"must be installed first, after having install ","position":{"start":{"line":100,"column":1},"end":{"line":100,"column":1}},"key":"NLoOATvDb2"},{"type":"inlineCode","value":"cython","position":{"start":{"line":100,"column":1},"end":{"line":100,"column":1}},"key":"Px1brFMad5"}],"key":"mjXHWb4rfQ"},{"type":"text","value":". It ables the use of physical quantities in script, which is quite convenient.","position":{"start":{"line":100,"column":1},"end":{"line":100,"column":1}},"key":"JS5eyTlTWJ"}],"key":"C7CYrZtASh"},{"type":"listItem","spread":true,"position":{"start":{"line":101,"column":1},"end":{"line":101,"column":1}},"children":[{"type":"link","url":"https://gitlab.in2p3.fr/gaz-quantiques-lcf/helium-1/qcontrol3_base","position":{"start":{"line":101,"column":1},"end":{"line":101,"column":1}},"children":[{"type":"inlineCode","value":"qcontrol3_base","position":{"start":{"line":101,"column":1},"end":{"line":101,"column":1}},"key":"fL3gUITwGW"}],"urlSource":"https://gitlab.in2p3.fr/gaz-quantiques-lcf/helium-1/qcontrol3_base","key":"FyZJiZyqHc"},{"type":"text","value":" is the core of the program : it contains the timing server which communicates with all the remote devices, the Adwin sequencer being one of them.","position":{"start":{"line":101,"column":1},"end":{"line":101,"column":1}},"key":"KjhJgoQwhZ"}],"key":"O59ZPCL9FC"},{"type":"listItem","spread":true,"position":{"start":{"line":102,"column":1},"end":{"line":102,"column":1}},"children":[{"type":"link","url":"https://gitlab.in2p3.fr/gaz-quantiques-lcf/helium-1/qcontrol3_driver_timing_adwin","position":{"start":{"line":102,"column":1},"end":{"line":102,"column":1}},"children":[{"type":"inlineCode","value":"qcontrol3_driver_timing_adwin","position":{"start":{"line":102,"column":1},"end":{"line":102,"column":1}},"key":"y4ulghdqvf"}],"urlSource":"https://gitlab.in2p3.fr/gaz-quantiques-lcf/helium-1/qcontrol3_driver_timing_adwin","key":"jcis2eVkAV"},{"type":"text","value":" is the driver that ables the QControl3 program to dialogs with the Adwin sequencer.","position":{"start":{"line":102,"column":1},"end":{"line":102,"column":1}},"key":"GeVxXHOVZD"}],"key":"cATbeIePIv"},{"type":"listItem","spread":true,"position":{"start":{"line":103,"column":1},"end":{"line":104,"column":1}},"children":[{"type":"link","url":"https://gitlab.in2p3.fr/gaz-quantiques-lcf/helium-1/qcontrol3_driver_timing_softwareremote","position":{"start":{"line":103,"column":1},"end":{"line":103,"column":1}},"children":[{"type":"inlineCode","value":"qcontrol3_driver_timing_softwareremote","position":{"start":{"line":103,"column":1},"end":{"line":103,"column":1}},"key":"IzFvpD0IwN"}],"urlSource":"https://gitlab.in2p3.fr/gaz-quantiques-lcf/helium-1/qcontrol3_driver_timing_softwareremote","key":"RDsXYjR58G"},{"type":"text","value":" is the driver that ables QControl3 to dialog with other remote devices than the Adwin Pro-II sequencer. It is not strictly speaking necessary to run a first sequence but it is a low level driver that will be rapidly needed, to control cameras or waveform generators for example.","position":{"start":{"line":103,"column":1},"end":{"line":103,"column":1}},"key":"otl7LqUXsN"}],"key":"N0pmdotsVv"}],"key":"DHSmOAC5Ct"},{"type":"paragraph","position":{"start":{"line":105,"column":1},"end":{"line":108,"column":1}},"children":[{"type":"text","value":"After installing those packages","position":{"start":{"line":105,"column":1},"end":{"line":105,"column":1}},"key":"JFmSrog7Sl"},{"type":"footnoteReference","identifier":"pip_install","label":"pip_install","position":{"start":{"line":105,"column":1},"end":{"line":105,"column":1}},"number":10,"enumerator":"10","key":"BAEb4kvK4I"},{"type":"text","value":", one should be able to run a first simple sequence. To dialog between the client (you) and the different server, QControl3 use ","position":{"start":{"line":105,"column":1},"end":{"line":105,"column":1}},"key":"Wkj6rWz1p1"},{"type":"link","url":"https://pyro4.readthedocs.io/en/stable/intro.html","position":{"start":{"line":105,"column":1},"end":{"line":105,"column":1}},"children":[{"type":"text","value":"Pyro","position":{"start":{"line":105,"column":1},"end":{"line":105,"column":1}},"key":"AA1QogevWw"}],"urlSource":"https://pyro4.readthedocs.io/en/stable/intro.html","key":"L3mhjhXPYI"},{"type":"text","value":" communication.\nTherefore, one must start by launching the ","position":{"start":{"line":105,"column":1},"end":{"line":105,"column":1}},"key":"BvvlJGfUgY"},{"type":"inlineCode","value":"name-server","position":{"start":{"line":105,"column":1},"end":{"line":105,"column":1}},"key":"PdY2t4kRPh"},{"type":"text","value":" in a terminal,\nwithin your virtual environment","position":{"start":{"line":105,"column":1},"end":{"line":105,"column":1}},"key":"BmxDloiKvs"},{"type":"footnoteReference","identifier":"name-server","label":"name-server","position":{"start":{"line":105,"column":1},"end":{"line":105,"column":1}},"number":12,"enumerator":"12","key":"I5nbl4cZmv"},{"type":"text","value":". In a new terminal, the\n","position":{"start":{"line":105,"column":1},"end":{"line":105,"column":1}},"key":"Kmpl3OktZV"},{"type":"inlineCode","value":"event-server","position":{"start":{"line":105,"column":1},"end":{"line":105,"column":1}},"key":"EFUG1KQaFM"},{"type":"text","value":" can be launch and will create several directories in your home directory:","position":{"start":{"line":105,"column":1},"end":{"line":105,"column":1}},"key":"KW3sukCc9h"}],"key":"uY4Ju5BY8f"},{"type":"list","ordered":false,"spread":false,"position":{"start":{"line":110,"column":1},"end":{"line":114,"column":1}},"children":[{"type":"listItem","spread":true,"position":{"start":{"line":110,"column":1},"end":{"line":110,"column":1}},"children":[{"type":"inlineCode","value":".qc3","position":{"start":{"line":110,"column":1},"end":{"line":110,"column":1}},"key":"lSrJAHmb1y"},{"type":"text","value":" stores the configuration file ","position":{"start":{"line":110,"column":1},"end":{"line":110,"column":1}},"key":"m3pOjdJtBN"},{"type":"inlineCode","value":"qc3conf.json","position":{"start":{"line":110,"column":1},"end":{"line":110,"column":1}},"key":"tcNxCzijpU"},{"type":"text","value":". It is initialized with default values and can be customized following ","position":{"start":{"line":110,"column":1},"end":{"line":110,"column":1}},"key":"QatqCqO5q9"},{"type":"link","url":"https://gitlab.in2p3.fr/gaz-quantiques-lcf/helium-1/qcontrol3_base/-/blob/master/doc/configuration/qc3conf.md","position":{"start":{"line":110,"column":1},"end":{"line":110,"column":1}},"children":[{"type":"text","value":"the documentation of the QControl3 base repository.","position":{"start":{"line":110,"column":1},"end":{"line":110,"column":1}},"key":"UF9pwghfZa"}],"urlSource":"https://gitlab.in2p3.fr/gaz-quantiques-lcf/helium-1/qcontrol3_base/-/blob/master/doc/configuration/qc3conf.md","key":"HcmhVub5ZO"}],"key":"qJ6Yiy4PD1"},{"type":"listItem","spread":true,"position":{"start":{"line":111,"column":1},"end":{"line":111,"column":1}},"children":[{"type":"inlineCode","value":"qc3data","position":{"start":{"line":111,"column":1},"end":{"line":111,"column":1}},"key":"XVTnGPgaQb"},{"type":"text","value":" stores the data after each experiment run.","position":{"start":{"line":111,"column":1},"end":{"line":111,"column":1}},"key":"Jk9v0OfQ7Q"}],"key":"NT69GHRA3Z"},{"type":"listItem","spread":true,"position":{"start":{"line":112,"column":1},"end":{"line":112,"column":1}},"children":[{"type":"inlineCode","value":"qc3log","position":{"start":{"line":112,"column":1},"end":{"line":112,"column":1}},"key":"mHbuvWmUho"},{"type":"text","value":" stores log messages.","position":{"start":{"line":112,"column":1},"end":{"line":112,"column":1}},"key":"a63QOukX54"}],"key":"Khhl1AR7rO"},{"type":"listItem","spread":true,"position":{"start":{"line":113,"column":1},"end":{"line":114,"column":1}},"children":[{"type":"inlineCode","value":"/qc3scripts","position":{"start":{"line":113,"column":1},"end":{"line":113,"column":1}},"key":"sTz8BpppW7"},{"type":"text","value":" will contain your script, subscripts and hardware configuration","position":{"start":{"line":113,"column":1},"end":{"line":113,"column":1}},"key":"cdtrWt11Ns"},{"type":"footnoteReference","identifier":"2","label":"2","position":{"start":{"line":113,"column":1},"end":{"line":113,"column":1}},"number":2,"enumerator":"2","key":"ANiTrw55Dv"},{"type":"text","value":".","position":{"start":{"line":113,"column":1},"end":{"line":113,"column":1}},"key":"qdgdCWkD3X"}],"key":"qLfDdBtly5"}],"key":"o5LvmrQtcB"},{"type":"container","kind":"code","label":"qc3scripts_content","identifier":"qc3scripts_content","children":[{"type":"code","lang":"shell","value":"+- qc3scripts\n       +- config\n       |  +- channels.py\n       |  +- hardware.py\n       - myscript.pys","key":"fRGz46giD6"},{"type":"caption","children":[{"type":"paragraph","children":[{"type":"captionNumber","kind":"code","label":"qc3scripts_content","identifier":"qc3scripts_content","html_id":"qc3scripts-content","enumerator":"1","children":[{"type":"text","value":"Code ","key":"loGwcFDST6"},{"type":"text","value":"1","key":"esm3mGn3Rc"},{"type":"text","value":":","key":"KF5IEtMCcT"}],"template":"Code %s:","key":"ZCxzZ0Icir"},{"type":"text","value":"Typical content of the qc3scripts directory.","position":{"start":{"line":117,"column":1},"end":{"line":117,"column":1}},"key":"GP1MonGwrf"}],"key":"VbdoFD9cYv"}],"key":"ZjwmGUcEPf"}],"enumerator":"1","html_id":"qc3scripts-content","key":"yKeHJl0IVd"},{"type":"paragraph","position":{"start":{"line":125,"column":1},"end":{"line":125,"column":1}},"children":[{"type":"text","value":"Summing up, we have now initiated both the name server and event server, essential prerequisites for launching the main server.","position":{"start":{"line":125,"column":1},"end":{"line":125,"column":1}},"key":"NPNf7KMXkr"}],"key":"LRcWbj8uuO"},{"type":"heading","depth":3,"position":{"start":{"line":127,"column":1},"end":{"line":127,"column":1}},"children":[{"type":"text","value":"Declaration of the hardware and user channels","position":{"start":{"line":127,"column":1},"end":{"line":127,"column":1}},"key":"znPS8HBlMj"}],"identifier":"declaration-of-the-hardware-and-user-channels","label":"Declaration of the hardware and user channels","html_id":"declaration-of-the-hardware-and-user-channels","implicit":true,"key":"lMIaxW8urA"},{"type":"paragraph","position":{"start":{"line":129,"column":1},"end":{"line":131,"column":1}},"children":[{"type":"text","value":"So far, properties of the hardware processor did not matter but this must now be configured in the\n","position":{"start":{"line":129,"column":1},"end":{"line":129,"column":1}},"key":"cyvrDA61UU"},{"type":"inlineCode","value":"qc3scripts","position":{"start":{"line":129,"column":1},"end":{"line":129,"column":1}},"key":"YCtj3XVCyh"},{"type":"text","value":" folder, which ","position":{"start":{"line":129,"column":1},"end":{"line":129,"column":1}},"key":"JPra6cWrjW"},{"type":"inlineCode","value":"config","position":{"start":{"line":129,"column":1},"end":{"line":129,"column":1}},"key":"AnxVKVUGD0"},{"type":"text","value":" folder will be read when launching the main server. The server will first import the ","position":{"start":{"line":129,"column":1},"end":{"line":129,"column":1}},"key":"wBsLk6YWKq"},{"type":"inlineCode","value":"hardware_setup","position":{"start":{"line":129,"column":1},"end":{"line":129,"column":1}},"key":"bq3mk3zyDM"},{"type":"text","value":" function from the ","position":{"start":{"line":129,"column":1},"end":{"line":129,"column":1}},"key":"ZQSkMB8cLZ"},{"type":"inlineCode","value":"hardware.py","position":{"start":{"line":129,"column":1},"end":{"line":129,"column":1}},"key":"hK3wAwLy66"},{"type":"text","value":" file. The argument that is passed to this function ","position":{"start":{"line":129,"column":1},"end":{"line":129,"column":1}},"key":"OM8XPMAwfu"},{"type":"emphasis","position":{"start":{"line":129,"column":1},"end":{"line":129,"column":1}},"children":[{"type":"text","value":"tsys","position":{"start":{"line":129,"column":1},"end":{"line":129,"column":1}},"key":"YNyrfINSiQ"}],"key":"lJQUyGjPTK"},{"type":"text","value":" is the timing system. This is the “","position":{"start":{"line":129,"column":1},"end":{"line":129,"column":1}},"key":"fEHrhgUb9W"},{"type":"emphasis","position":{"start":{"line":129,"column":1},"end":{"line":129,"column":1}},"children":[{"type":"text","value":"the root instance of the hardware tree on which one should add your timing controllers.","position":{"start":{"line":129,"column":1},"end":{"line":129,"column":1}},"key":"MpJFZCLrMe"}],"key":"XxB0wFDx2O"},{"type":"text","value":"” In QControl language, a timing controller is a complex object with timing channels, that often dialog with an external device. In the example we provide in ","position":{"start":{"line":129,"column":1},"end":{"line":129,"column":1}},"key":"dZIn2RXyqw"},{"type":"crossReference","position":{"start":{"line":129,"column":1},"end":{"line":129,"column":1}},"children":[{"type":"text","value":"Program ","key":"sbglDZtbG3"},{"type":"text","value":"2","key":"glycJuPQy0"}],"identifier":"config-hardware_minimal_example","label":"config-hardware_minimal_example","kind":"code","template":"Program %s","enumerator":"2","resolved":true,"html_id":"config-hardware-minimal-example","key":"uVnYVnXsSf"},{"type":"text","value":", we add to the timing system the Adwin Timing Controller.\nNote that in the declaration of the Adwin Timing Controller, one must specified the device number and the number of different cards used. The device number must match the one set previously using the adPro software in subsection ","position":{"start":{"line":129,"column":1},"end":{"line":129,"column":1}},"key":"xAr8zE8Cyg"},{"type":"crossReference","position":{"start":{"line":129,"column":1},"end":{"line":129,"column":1}},"children":[{"type":"text","value":"Adwin Pro-II hardware configuration","position":{"start":{"line":52,"column":1},"end":{"line":52,"column":1}},"key":"RgkZkXL2qz"}],"identifier":"subsection-adwin-hardware-config","label":"subsection-adwin-hardware-config","kind":"heading","template":"{name}","resolved":true,"html_id":"subsection-adwin-hardware-config","key":"c2mq9zASzp"},{"type":"text","value":".","position":{"start":{"line":129,"column":1},"end":{"line":129,"column":1}},"key":"pLnRCl2Kff"}],"key":"jBxUY9hvU9"},{"type":"container","kind":"code","label":"config-hardware_minimal_example","identifier":"config-hardware_minimal_example","children":[{"type":"code","lang":"python","filename":"qc3cripts/config/hardware.py","value":"from qcontrol3.driver.timing.adwin import AdwinTimingController\n\ndef hardware_setup(tsys):\n    \"\"\"Define the hardware setup.\n    Parameters\n    ----------\n    tsys : TimingSystem\n        The root instance of the hardware tree. Add your timing controllers to it.\n    \"\"\"\n    adw = AdwinTimingController(\n        \"ADWIN0\",\n        processor=12,\n        number_dio32=1,\n        number_aout8_16=1,\n        device_number=1,\n        is_dummy=False,\n    )\n    tsys.add_child(adw)\n    tsys.set_master_by_name(\"ADWIN0\") # set the master timing controller for the system.","key":"rw2JIGxYVQ"},{"type":"caption","children":[{"type":"paragraph","children":[{"type":"captionNumber","kind":"code","label":"config-hardware_minimal_example","identifier":"config-hardware_minimal_example","html_id":"config-hardware-minimal-example","enumerator":"2","children":[{"type":"text","value":"Code ","key":"PF9PflcVl2"},{"type":"text","value":"2","key":"SLFODuVjf6"},{"type":"text","value":":","key":"oFxyf1IX2y"}],"template":"Code %s:","key":"oKMQBOm4Qp"},{"type":"text","value":"Minimal example for the file ","position":{"start":{"line":135,"column":1},"end":{"line":135,"column":1}},"key":"BADWWvsh9K"},{"type":"inlineCode","value":"hardware.py","position":{"start":{"line":135,"column":1},"end":{"line":135,"column":1}},"key":"HklWSRKIB6"},{"type":"text","value":". Tests can be perform disconnected from the real sequencer by setting the adwin system dummy.","position":{"start":{"line":135,"column":1},"end":{"line":135,"column":1}},"key":"EvRovFJotp"}],"key":"LlzmquC8wb"}],"key":"dfK7v2e0A2"}],"enumerator":"2","html_id":"config-hardware-minimal-example","key":"XLLmO3Ngjj"},{"type":"paragraph","position":{"start":{"line":158,"column":1},"end":{"line":158,"column":1}},"children":[{"type":"text","value":"Timing controllers like the Adwin Timing Controller contains several timing channels but one must now create so-called ","position":{"start":{"line":158,"column":1},"end":{"line":158,"column":1}},"key":"sQ0KFxylxw"},{"type":"emphasis","position":{"start":{"line":158,"column":1},"end":{"line":158,"column":1}},"children":[{"type":"text","value":"user_channels","position":{"start":{"line":158,"column":1},"end":{"line":158,"column":1}},"key":"AVOzK4yhf9"}],"key":"BkAA1D0jtj"},{"type":"text","value":" so that the user is able to interact with them. This is done in the ","position":{"start":{"line":158,"column":1},"end":{"line":158,"column":1}},"key":"T8cuVxlIok"},{"type":"inlineCode","value":"channels.py","position":{"start":{"line":158,"column":1},"end":{"line":158,"column":1}},"key":"SaM8LqhvL7"},{"type":"text","value":" file. In the ","position":{"start":{"line":158,"column":1},"end":{"line":158,"column":1}},"key":"RnmGNeftKN"},{"type":"crossReference","position":{"start":{"line":158,"column":1},"end":{"line":158,"column":1}},"children":[{"type":"text","value":"Program ","key":"l3wyRVFHsm"},{"type":"text","value":"3","key":"JEnq4CyvoT"}],"identifier":"config-channels_minimal_example","label":"config-channels_minimal_example","kind":"code","template":"Program %s","enumerator":"3","resolved":true,"html_id":"config-channels-minimal-example","key":"VdBncUuf1Z"},{"type":"text","value":", we create two user channels : one is digital while the other is an analog channel.","position":{"start":{"line":158,"column":1},"end":{"line":158,"column":1}},"key":"K99pf99i2w"}],"key":"JFM1NJeex2"},{"type":"container","kind":"code","label":"config-channels_minimal_example","identifier":"config-channels_minimal_example","children":[{"type":"code","lang":"python","filename":"qc3scripts/config/channels.py","value":"import os\nfrom qcontrol3.tools.units import u\n\norgdir = os.getcwd() # change the directory for easy usage of subdirs\nos.chdir(os.path.dirname(__file__))\ndef channel_setup(tsys):\n    tch = tsys.get_node(\"ADWIN0.DIO0.DO01\")\n    tch.create_user_channel(\"DIGITAL_01\", \n       \"Description of my digital output 01\", \n       default_value=False) \n    tch = tsys.get_node(\"ADWIN0.AOUT0.AO4\")\n    tch.create_user_channel(\"ANALOG_04\", \n       \"Description of my fivth analog output\", \n       default_value=0*u.V) \nos.chdir(orgdir) # change the directory back","key":"OX53pZZ63C"},{"type":"caption","children":[{"type":"paragraph","children":[{"type":"captionNumber","kind":"code","label":"config-channels_minimal_example","identifier":"config-channels_minimal_example","html_id":"config-channels-minimal-example","enumerator":"3","children":[{"type":"text","value":"Code ","key":"o1dEVLJ1jK"},{"type":"text","value":"3","key":"txBN83uP3m"},{"type":"text","value":":","key":"kpLHTymyRw"}],"template":"Code %s:","key":"z249qYBC0m"},{"type":"text","value":"Creation of two user channels from timing system nodes. Note that one can display the timing system tree ","position":{"start":{"line":162,"column":1},"end":{"line":162,"column":1}},"key":"QxjMjHJuBD"},{"type":"inlineCode","value":"tsys.tree","position":{"start":{"line":162,"column":1},"end":{"line":162,"column":1}},"key":"SIWLNXY5Tn"},{"type":"text","value":" to check available timing channels.","position":{"start":{"line":162,"column":1},"end":{"line":162,"column":1}},"key":"dH1WW2APOe"}],"key":"K9sAsn7lD0"}],"key":"C5POT7UoV7"}],"enumerator":"3","html_id":"config-channels-minimal-example","key":"HGGUiqDAel"},{"type":"paragraph","position":{"start":{"line":181,"column":1},"end":{"line":181,"column":1}},"children":[{"type":"text","value":"Once the hardware is declared, ","position":{"start":{"line":181,"column":1},"end":{"line":181,"column":1}},"key":"PgVyFML5nc"},{"type":"emphasis","position":{"start":{"line":181,"column":1},"end":{"line":181,"column":1}},"children":[{"type":"text","value":"User Channel","position":{"start":{"line":181,"column":1},"end":{"line":181,"column":1}},"key":"EdThJOy0CD"}],"key":"OOJOuGfemD"},{"type":"text","value":" must be created in a ","position":{"start":{"line":181,"column":1},"end":{"line":181,"column":1}},"key":"uLwNSlNcEd"},{"type":"inlineCode","value":"channels.py","position":{"start":{"line":181,"column":1},"end":{"line":181,"column":1}},"key":"z2hNBpWNYY"},{"type":"text","value":" file: this will able the client to access and modify the values of timing channels. ","position":{"start":{"line":181,"column":1},"end":{"line":181,"column":1}},"key":"zSA2SZJqTp"},{"type":"emphasis","position":{"start":{"line":181,"column":1},"end":{"line":181,"column":1}},"children":[{"type":"text","value":"User Channels","position":{"start":{"line":181,"column":1},"end":{"line":181,"column":1}},"key":"Bd5Kvsa4DT"}],"key":"aQIw5uBB7b"},{"type":"text","value":" are created using the ","position":{"start":{"line":181,"column":1},"end":{"line":181,"column":1}},"key":"MnNdnykhcO"},{"type":"inlineCode","value":"create_user_channel","position":{"start":{"line":181,"column":1},"end":{"line":181,"column":1}},"key":"yAOoiXwBPE"},{"type":"text","value":" method which take as argument a name","position":{"start":{"line":181,"column":1},"end":{"line":181,"column":1}},"key":"t68xMYMQ8C"},{"type":"footnoteReference","identifier":"user_channel_name","label":"user_channel_name","position":{"start":{"line":181,"column":1},"end":{"line":181,"column":1}},"number":13,"enumerator":"13","key":"ZSYP0W0xqH"},{"type":"text","value":", a description and a default value. The later will be set at the beginning of each cycle. Once a ","position":{"start":{"line":181,"column":1},"end":{"line":181,"column":1}},"key":"PPlXTSasfM"},{"type":"emphasis","position":{"start":{"line":181,"column":1},"end":{"line":181,"column":1}},"children":[{"type":"text","value":"User Channel","position":{"start":{"line":181,"column":1},"end":{"line":181,"column":1}},"key":"AMVMS3iAkZ"}],"key":"s0bjeTAAi7"},{"type":"text","value":" has been created, its value can be changed with the ","position":{"start":{"line":181,"column":1},"end":{"line":181,"column":1}},"key":"s31osHnJyT"},{"type":"inlineCode","value":"qcontrol3-client","position":{"start":{"line":181,"column":1},"end":{"line":181,"column":1}},"key":"TAtR9XnYty"},{"type":"text","value":" and it is accessible in any file with the ","position":{"start":{"line":181,"column":1},"end":{"line":181,"column":1}},"key":"GbNaTbFaVd"},{"type":"inlineCode","value":".pys","position":{"start":{"line":181,"column":1},"end":{"line":181,"column":1}},"key":"bntlCBCfj9"},{"type":"text","value":" extension.","position":{"start":{"line":181,"column":1},"end":{"line":181,"column":1}},"key":"Tlk6QocgBj"}],"key":"xhuELAJVG2"},{"type":"paragraph","position":{"start":{"line":183,"column":1},"end":{"line":183,"column":1}},"children":[{"type":"text","value":"Once those file are completed, the last configuration step is to launch the server running the ","position":{"start":{"line":183,"column":1},"end":{"line":183,"column":1}},"key":"v64M583VbK"},{"type":"inlineCode","value":"qcontrol3-server","position":{"start":{"line":183,"column":1},"end":{"line":183,"column":1}},"key":"LnKWoqxpt2"},{"type":"text","value":" command. If an error occurs at this stage, it probably means that there is an error in the hardware and/or channel declaration.","position":{"start":{"line":183,"column":1},"end":{"line":183,"column":1}},"key":"DY2UBUEewG"}],"key":"DiKJttnbOQ"},{"type":"heading","depth":3,"position":{"start":{"line":185,"column":1},"end":{"line":185,"column":1}},"children":[{"type":"text","value":"Communicating with the qcontrol3-client","position":{"start":{"line":185,"column":1},"end":{"line":185,"column":1}},"key":"YXoniOKFZB"}],"identifier":"communicating-with-the-qcontrol3-client","label":"Communicating with the qcontrol3-client","html_id":"communicating-with-the-qcontrol3-client","implicit":true,"key":"YMXG2n9Qto"},{"type":"paragraph","position":{"start":{"line":187,"column":1},"end":{"line":187,"column":1}},"children":[{"type":"text","value":"Any command that a user want to send to the server must passes through the client called ","position":{"start":{"line":187,"column":1},"end":{"line":187,"column":1}},"key":"KZH4UEfTTC"},{"type":"link","url":"https://gitlab.in2p3.fr/gaz-quantiques-lcf/helium-1/qcontrol3_base/bin/qcontrol3-client","position":{"start":{"line":187,"column":1},"end":{"line":187,"column":1}},"children":[{"type":"inlineCode","value":"qcontrol3-client","position":{"start":{"line":187,"column":1},"end":{"line":187,"column":1}},"key":"zUZihyCzBw"}],"urlSource":"https://gitlab.in2p3.fr/gaz-quantiques-lcf/helium-1/qcontrol3_base/bin/qcontrol3-client","key":"LlaGhK0yAe"},{"type":"text","value":". I will not list all the client functionalities but restrict myself to some of them. The ","position":{"start":{"line":187,"column":1},"end":{"line":187,"column":1}},"key":"gWWe0Atqpj"},{"type":"inlineCode","value":"set_channel_value","position":{"start":{"line":187,"column":1},"end":{"line":187,"column":1}},"key":"HTXx8znlsa"},{"type":"text","value":" function ables to change a value of a timing channel: it must be followed by the name of the user channel associated to this timing channel and by its value. The type of the value depends on the type of the channel: it is a boolean for digital outputs and a string with a voltage unit for analog outputs. For example, with the configuration and the user channels declared in","position":{"start":{"line":187,"column":1},"end":{"line":187,"column":1}},"key":"PPvYT3goMF"},{"type":"crossReference","position":{"start":{"line":187,"column":1},"end":{"line":187,"column":1}},"children":[{"type":"text","value":"Program ","key":"SBBfd8iBrX"},{"type":"text","value":"2","key":"uaTRX7aMzo"}],"identifier":"config-hardware_minimal_example","label":"config-hardware_minimal_example","kind":"code","template":"Program %s","enumerator":"2","resolved":true,"html_id":"config-hardware-minimal-example","key":"d4rtG4eS2G"},{"type":"text","value":" and ","position":{"start":{"line":187,"column":1},"end":{"line":187,"column":1}},"key":"akFwiHqIck"},{"type":"crossReference","position":{"start":{"line":187,"column":1},"end":{"line":187,"column":1}},"children":[{"type":"text","value":"Program ","key":"WtoEcmMlEt"},{"type":"text","value":"3","key":"hQHuhR9hhu"}],"identifier":"config-channels_minimal_example","label":"config-channels_minimal_example","kind":"code","template":"Program %s","enumerator":"3","resolved":true,"html_id":"config-channels-minimal-example","key":"sZGZUREzU4"},{"type":"text","value":" one could send the following commands to the server:","position":{"start":{"line":187,"column":1},"end":{"line":187,"column":1}},"key":"LPsQnCQXW9"}],"key":"b5JxaMzINZ"},{"type":"code","lang":"shell","value":"$ qcontrol3-client set_channel_value DO0_01 True\n$ qcontrol3-client set_channel_value AOUT0_4 \"6 V\"","key":"vNEOlO9Np1"},{"type":"paragraph","position":{"start":{"line":194,"column":1},"end":{"line":194,"column":1}},"children":[{"type":"text","value":"The ","position":{"start":{"line":194,"column":1},"end":{"line":194,"column":1}},"key":"D8YUXEVaQA"},{"type":"inlineCode","value":"reset_defaults","position":{"start":{"line":194,"column":1},"end":{"line":194,"column":1}},"key":"LkqX7Ly9lL"},{"type":"text","value":" command resets all timing channels to their default value that was set when instancing the associated user channel.","position":{"start":{"line":194,"column":1},"end":{"line":194,"column":1}},"key":"Y4a7dCMIBe"}],"key":"POBLHE7EUS"},{"type":"paragraph","position":{"start":{"line":196,"column":1},"end":{"line":196,"column":1}},"children":[{"type":"text","value":"To run a script, one must first create a file whose extension is “pys” in the qc3script repository. This ables the script to access global variables like ","position":{"start":{"line":196,"column":1},"end":{"line":196,"column":1}},"key":"HNIiQ6YQRW"},{"type":"inlineCode","value":"iter_step","position":{"start":{"line":196,"column":1},"end":{"line":196,"column":1}},"key":"rrw26aeFEe"},{"type":"text","value":", ","position":{"start":{"line":196,"column":1},"end":{"line":196,"column":1}},"key":"qnBVAnRLH3"},{"type":"inlineCode","value":"iter_value","position":{"start":{"line":196,"column":1},"end":{"line":196,"column":1}},"key":"wSKZ8ftrHl"},{"type":"text","value":" as we shall see after. To run a script, the user must first declare which file should be upload, then upload it and finally run it :","position":{"start":{"line":196,"column":1},"end":{"line":196,"column":1}},"key":"V0CAFOZJ1w"}],"key":"WhneNKqBBH"},{"type":"code","lang":"shell","value":"$ qcontrol3-client set_pys_file my-script-name.pys\n$ qcontrol3-client upload_task\n$ qcontrol3-client run_single","key":"bdjORyM91i"},{"type":"paragraph","position":{"start":{"line":204,"column":1},"end":{"line":204,"column":1}},"children":[{"type":"text","value":"It exists three different running modes :","position":{"start":{"line":204,"column":1},"end":{"line":204,"column":1}},"key":"nCgEhcjtKN"}],"key":"IwWk0bRsiO"},{"type":"list","ordered":false,"spread":false,"position":{"start":{"line":206,"column":1},"end":{"line":209,"column":1}},"children":[{"type":"listItem","spread":true,"position":{"start":{"line":206,"column":1},"end":{"line":206,"column":1}},"children":[{"type":"inlineCode","value":"run_single","position":{"start":{"line":206,"column":1},"end":{"line":206,"column":1}},"key":"kLP0SV4jvx"},{"type":"text","value":" : the task runs only once and the system stops when the task is over,","position":{"start":{"line":206,"column":1},"end":{"line":206,"column":1}},"key":"gO6Eotd7Vn"}],"key":"ny15QSd7re"},{"type":"listItem","spread":true,"position":{"start":{"line":207,"column":1},"end":{"line":207,"column":1}},"children":[{"type":"inlineCode","value":"run_looped","position":{"start":{"line":207,"column":1},"end":{"line":207,"column":1}},"key":"xFbawd3Rd0"},{"type":"text","value":" : the task is run while the user stops the execution with the ","position":{"start":{"line":207,"column":1},"end":{"line":207,"column":1}},"key":"MqQUCbWXPM"},{"type":"inlineCode","value":"qcontrol3-client stop","position":{"start":{"line":207,"column":1},"end":{"line":207,"column":1}},"key":"QFgbPy0vtg"},{"type":"text","value":" command.","position":{"start":{"line":207,"column":1},"end":{"line":207,"column":1}},"key":"QG2omWLe87"}],"key":"pf5EtjacW8"},{"type":"listItem","spread":true,"position":{"start":{"line":208,"column":1},"end":{"line":209,"column":1}},"children":[{"type":"inlineCode","value":"run_iteration","position":{"start":{"line":208,"column":1},"end":{"line":208,"column":1}},"key":"q1Tff99GV9"},{"type":"text","value":" : the task is run but the script is executed several times. A list, called ","position":{"start":{"line":208,"column":1},"end":{"line":208,"column":1}},"key":"Q7TJOftp3x"},{"type":"inlineCode","value":"iter_list","position":{"start":{"line":208,"column":1},"end":{"line":208,"column":1}},"key":"QvndtvSTvg"},{"type":"text","value":" is browsed as the iteration progress. Two name reserved variables ","position":{"start":{"line":208,"column":1},"end":{"line":208,"column":1}},"key":"UQCByXPvhD"},{"type":"inlineCode","value":"iter_step","position":{"start":{"line":208,"column":1},"end":{"line":208,"column":1}},"key":"k4xO7oIAEs"},{"type":"text","value":", ranging from 0 to the size of the list uninclosed and ","position":{"start":{"line":208,"column":1},"end":{"line":208,"column":1}},"key":"YPSvlTejSl"},{"type":"inlineCode","value":"iter_value","position":{"start":{"line":208,"column":1},"end":{"line":208,"column":1}},"key":"LF7qosEljK"},{"type":"text","value":", which takes a value of the ","position":{"start":{"line":208,"column":1},"end":{"line":208,"column":1}},"key":"qAGd0QbNQn"},{"type":"inlineCode","value":"iter_list","position":{"start":{"line":208,"column":1},"end":{"line":208,"column":1}},"key":"L4lJU9vmKn"},{"type":"text","value":" at each iteration represent the progress of the iteration. The idea behind it is to enable the scan of a parameter in the script.","position":{"start":{"line":208,"column":1},"end":{"line":208,"column":1}},"key":"UykWXgD3wp"}],"key":"SHROWs89v8"}],"key":"jUdH5EpyGG"},{"type":"paragraph","position":{"start":{"line":210,"column":1},"end":{"line":210,"column":1}},"children":[{"type":"text","value":"Before going into greater details on how to write a script, let’s mention that the ","position":{"start":{"line":210,"column":1},"end":{"line":210,"column":1}},"key":"YNEdr3ZVzN"},{"type":"inlineCode","value":"upload_and_run_single script.pys","position":{"start":{"line":210,"column":1},"end":{"line":210,"column":1}},"key":"b88FEUQIGM"},{"type":"text","value":" command ables to declare, upload and run a script file. This commands exist also for iteration and looped modes.","position":{"start":{"line":210,"column":1},"end":{"line":210,"column":1}},"key":"PqWeaffeGN"}],"key":"nGDNf2U6Vc"},{"type":"heading","depth":3,"position":{"start":{"line":212,"column":1},"end":{"line":212,"column":1}},"children":[{"type":"text","value":"Running a first script","position":{"start":{"line":212,"column":1},"end":{"line":212,"column":1}},"key":"GPEUF1ZlNH"}],"identifier":"running-a-first-script","label":"Running a first script","html_id":"running-a-first-script","implicit":true,"key":"LRyr2LAFp4"},{"type":"paragraph","position":{"start":{"line":214,"column":1},"end":{"line":214,"column":1}},"children":[{"type":"text","value":"A script inherits from the ","position":{"start":{"line":214,"column":1},"end":{"line":214,"column":1}},"key":"c7wyaKNXex"},{"type":"link","url":"https://gitlab.in2p3.fr/gaz-quantiques-lcf/helium-1/qcontrol3_base/-/blob/master/qcontrol3/server/script.py","position":{"start":{"line":214,"column":1},"end":{"line":214,"column":1}},"children":[{"type":"text","value":"Script class","position":{"start":{"line":214,"column":1},"end":{"line":214,"column":1}},"key":"u3EYz0oJig"}],"urlSource":"https://gitlab.in2p3.fr/gaz-quantiques-lcf/helium-1/qcontrol3_base/-/blob/master/qcontrol3/server/script.py","key":"KSnuqHCLh9"},{"type":"text","value":" and must be save with the ","position":{"start":{"line":214,"column":1},"end":{"line":214,"column":1}},"key":"Gkd8KXFwoI"},{"type":"link","url":"https://gitlab.in2p3.fr/gaz-quantiques-lcf/helium-1/qcontrol3_base/-/blob/master/qcontrol3/server/pysmanager.py","position":{"start":{"line":214,"column":1},"end":{"line":214,"column":1}},"children":[{"type":"text","value":"“","position":{"start":{"line":214,"column":1},"end":{"line":214,"column":1}},"key":"RGAKipA5ry"},{"type":"inlineCode","value":".pys","position":{"start":{"line":214,"column":1},"end":{"line":214,"column":1}},"key":"DM0Ce2DMmU"},{"type":"text","value":"”","position":{"start":{"line":214,"column":1},"end":{"line":214,"column":1}},"key":"CxlUWbLFIm"}],"urlSource":"https://gitlab.in2p3.fr/gaz-quantiques-lcf/helium-1/qcontrol3_base/-/blob/master/qcontrol3/server/pysmanager.py","key":"pod8782RjE"},{"type":"text","value":" extension so that it has access to global variables such as ","position":{"start":{"line":214,"column":1},"end":{"line":214,"column":1}},"key":"xIre3upwL6"},{"type":"inlineCode","value":"iter_list","position":{"start":{"line":214,"column":1},"end":{"line":214,"column":1}},"key":"emuwMLHqQX"},{"type":"text","value":", user channels defined in ","position":{"start":{"line":214,"column":1},"end":{"line":214,"column":1}},"key":"t1udAF1UrX"},{"type":"inlineCode","value":"channels.py","position":{"start":{"line":214,"column":1},"end":{"line":214,"column":1}},"key":"hYuW846lRy"},{"type":"text","value":" file or other global variables in QControl. In a script, the basic syntax to add an event on a timing channel is ","position":{"start":{"line":214,"column":1},"end":{"line":214,"column":1}},"key":"HDPHxyIA8K"},{"type":"inlineCode","value":"add(t, val)","position":{"start":{"line":214,"column":1},"end":{"line":214,"column":1}},"key":"gDPjn5V1Az"},{"type":"text","value":" where ","position":{"start":{"line":214,"column":1},"end":{"line":214,"column":1}},"key":"F61i3SC46u"},{"type":"inlineCode","value":"t","position":{"start":{"line":214,"column":1},"end":{"line":214,"column":1}},"key":"gO1amBMTZ2"},{"type":"text","value":" is the time at which the channel must take the value ","position":{"start":{"line":214,"column":1},"end":{"line":214,"column":1}},"key":"WjKFnQLXZG"},{"type":"inlineCode","value":"val","position":{"start":{"line":214,"column":1},"end":{"line":214,"column":1}},"key":"QehLxBGPLU"},{"type":"footnoteReference","identifier":"5","label":"5","position":{"start":{"line":214,"column":1},"end":{"line":214,"column":1}},"number":5,"enumerator":"5","key":"EyaW6yDwlD"},{"type":"text","value":". An example of a minimal script file is given in  ","position":{"start":{"line":214,"column":1},"end":{"line":214,"column":1}},"key":"EM7UTZEbD5"},{"type":"crossReference","position":{"start":{"line":214,"column":1},"end":{"line":214,"column":1}},"children":[{"type":"text","value":"Program ","key":"DA2u2NMpuc"},{"type":"text","value":"4","key":"HLopn6fitJ"}],"identifier":"qc3script-basic","label":"qc3script-basic","kind":"code","template":"Program %s","enumerator":"4","resolved":true,"html_id":"qc3script-basic","key":"LKfn1KTYKz"},{"type":"text","value":".","position":{"start":{"line":214,"column":1},"end":{"line":214,"column":1}},"key":"qAAlhd54dN"}],"key":"KsESGpbsXP"},{"type":"container","kind":"code","label":"qc3script-basic","identifier":"qc3script-basic","children":[{"type":"code","lang":"python","filename":"qc3scripts/myscript.pys","value":"from qcontrol3.server.script import Script\nfrom qcontrol3.tools.units import u\n\niter_list = [1, 2, 3, 4]\nclass MyScript(Script):\n   def __init__(self):\n        super().__init__()\n\n    def main(self):\n        time = 10.0 * u.ms  # absolute deadtime for Adwin sequencer\n        DIGITAL_01.add(time, True)\n        DIGITAL_01.add(time + (1 + iter_step) * 10 * u.ms, False)\n        time += 220 * u.ms\n        ANALOG_04.add(time, 2 * u.V)\ntiming_script = MyScript()","key":"MeiKcSF2h2"},{"type":"caption","children":[{"type":"paragraph","children":[{"type":"captionNumber","kind":"code","label":"qc3script-basic","identifier":"qc3script-basic","html_id":"qc3script-basic","enumerator":"4","children":[{"type":"text","value":"Code ","key":"WuvobGkeqM"},{"type":"text","value":"4","key":"Y02Dkgc4ox"},{"type":"text","value":":","key":"xUOolRdOEY"}],"template":"Code %s:","key":"cGGP3HiHdQ"},{"type":"text","value":"Basic script in which we change the value of a digital user channel to True and False at various time and the value of an analog channel to 2 V a bit later. Note that the user channel name used in this script is the one declared in the ","position":{"start":{"line":218,"column":1},"end":{"line":218,"column":1}},"key":"bcfygEcFQ8"},{"type":"crossReference","position":{"start":{"line":218,"column":1},"end":{"line":218,"column":1}},"children":[{"type":"inlineCode","value":"channels.py","position":{"start":{"line":218,"column":1},"end":{"line":218,"column":1}},"key":"FEMHtZSW5R"},{"type":"text","value":" file","position":{"start":{"line":218,"column":1},"end":{"line":218,"column":1}},"key":"QeL7zojlZO"}],"identifier":"config-channels_minimal_example","label":"config-channels_minimal_example","kind":"code","template":"Program %s","enumerator":"3","resolved":true,"html_id":"config-channels-minimal-example","key":"UOq7Ngfk5Z"},{"type":"text","value":". Because this script has the .pys extension, it has access to user channels and iter_list related properties (see text). QControl3 will then call the ","position":{"start":{"line":218,"column":1},"end":{"line":218,"column":1}},"key":"ku6ews6Hm3"},{"type":"inlineCode","value":"main","position":{"start":{"line":218,"column":1},"end":{"line":218,"column":1}},"key":"aPjeeZOcmh"},{"type":"text","value":" method of the timing script.","position":{"start":{"line":218,"column":1},"end":{"line":218,"column":1}},"key":"kCGTvOUlHO"}],"key":"DygackWj6E"}],"key":"DN1RVQMXv4"}],"enumerator":"4","html_id":"qc3script-basic","key":"x93TYpbUj6"},{"type":"paragraph","position":{"start":{"line":237,"column":1},"end":{"line":237,"column":1}},"children":[{"type":"text","value":"However, the idea is not to use directly user channels in the main script but to wrap them into more complex object, tht should inherits from the ","position":{"start":{"line":237,"column":1},"end":{"line":237,"column":1}},"key":"K0N4QKlAyW"},{"type":"link","url":"https://gitlab.in2p3.fr/gaz-quantiques-lcf/helium-1/qcontrol3_base/qcontrol3/server/script.py","position":{"start":{"line":237,"column":1},"end":{"line":237,"column":1}},"children":[{"type":"inlineCode","value":"ScriptObjects","position":{"start":{"line":237,"column":1},"end":{"line":237,"column":1}},"key":"cj40GifFWB"},{"type":"text","value":" class","position":{"start":{"line":237,"column":1},"end":{"line":237,"column":1}},"key":"VYsDrtaqB9"}],"urlSource":"https://gitlab.in2p3.fr/gaz-quantiques-lcf/helium-1/qcontrol3_base/qcontrol3/server/script.py","key":"LN56anO63a"},{"type":"text","value":". Regarding this,  (","position":{"start":{"line":237,"column":1},"end":{"line":237,"column":1}},"key":"notPndwgmZ"},{"type":"link","url":"https://gitlab.in2p3.fr/gaz-quantiques-lcf/helium-1/qcontrol3_base/qcontrol3/scripts/base/digital.py","position":{"start":{"line":237,"column":1},"end":{"line":237,"column":1}},"children":[{"type":"text","value":"DigitalObjects","position":{"start":{"line":237,"column":1},"end":{"line":237,"column":1}},"key":"VvvIqlimcr"}],"urlSource":"https://gitlab.in2p3.fr/gaz-quantiques-lcf/helium-1/qcontrol3_base/qcontrol3/scripts/base/digital.py","key":"k1Kaxuph6Y"},{"type":"text","value":") and analog outputs (","position":{"start":{"line":237,"column":1},"end":{"line":237,"column":1}},"key":"cvmv2uFPFp"},{"type":"link","url":"https://gitlab.in2p3.fr/gaz-quantiques-lcf/helium-1/qcontrol3_base/qcontrol3/scripts/base/analog.py","position":{"start":{"line":237,"column":1},"end":{"line":237,"column":1}},"children":[{"type":"text","value":"AnalogObjects","position":{"start":{"line":237,"column":1},"end":{"line":237,"column":1}},"key":"uWdjKLyLi5"}],"urlSource":"https://gitlab.in2p3.fr/gaz-quantiques-lcf/helium-1/qcontrol3_base/qcontrol3/scripts/base/analog.py","key":"o2bBuhF19L"},{"type":"text","value":") are already defined in ","position":{"start":{"line":237,"column":1},"end":{"line":237,"column":1}},"key":"xsuaY7P5Io"},{"type":"inlineCode","value":"qcontrol3_base","position":{"start":{"line":237,"column":1},"end":{"line":237,"column":1}},"key":"AkBrLm21Uv"},{"type":"text","value":", with methods that conveys more their purpose than the ","position":{"start":{"line":237,"column":1},"end":{"line":237,"column":1}},"key":"mwlauMKdS1"},{"type":"inlineCode","value":"add","position":{"start":{"line":237,"column":1},"end":{"line":237,"column":1}},"key":"uOEgHIGsbH"},{"type":"text","value":" method. For our current example, one could define objects in a different file (here devices.pys) that should be imported in the main script.","position":{"start":{"line":237,"column":1},"end":{"line":237,"column":1}},"key":"LRh7P2An0B"}],"key":"YCClUPyyiw"},{"type":"container","kind":"code","label":"qc3script-devices","identifier":"qc3script-devices","children":[{"type":"code","lang":"python","filename":"qc3scripts/devices.pys","value":"from qcontrol3.server.script import ScriptObject\nfrom qcontrol3.scripts.base.digital import DigitalObject, Shutter\nfrom qcontrol3.scripts.base.analog import AnalogObject\n\nclass ScriptDevices(ScriptObject):\n    def __init__(self) -> None:\n        super().__init__()\n    self.molasses_shutter = Shutter(DIGITAL_01)\n    self.mot_aom = AnalogObject(ANALOG_04)","key":"BHSLUBy9cx"},{"type":"caption","children":[{"type":"paragraph","children":[{"type":"captionNumber","kind":"code","label":"qc3script-devices","identifier":"qc3script-devices","html_id":"qc3script-devices","enumerator":"5","children":[{"type":"text","value":"Code ","key":"qo6fmzrDh0"},{"type":"text","value":"5","key":"zUQCRiUzSz"},{"type":"text","value":":","key":"i98OlLo9lj"}],"template":"Code %s:","key":"mkxfBAQZER"},{"type":"text","value":"This file wraps user channels into more compex objects that will be used by the final user.","position":{"start":{"line":241,"column":1},"end":{"line":241,"column":1}},"key":"zWLO8nTWkb"}],"key":"TG3rCLwBNO"}],"key":"XdX7yn2PYX"}],"enumerator":"5","html_id":"qc3script-devices","key":"xD7SR44GSo"},{"type":"paragraph","position":{"start":{"line":253,"column":1},"end":{"line":253,"column":1}},"children":[{"type":"text","value":"In this case, the ","position":{"start":{"line":253,"column":1},"end":{"line":253,"column":1}},"key":"qUPV6tcuQD"},{"type":"inlineCode","value":"main","position":{"start":{"line":253,"column":1},"end":{"line":253,"column":1}},"key":"EG5LQaItt0"},{"type":"text","value":" function of the script could read","position":{"start":{"line":253,"column":1},"end":{"line":253,"column":1}},"key":"XP3IUBwCYH"}],"key":"nTkuGOC3L4"},{"type":"container","kind":"code","label":"qc3script-level1","identifier":"qc3script-level1","children":[{"type":"code","lang":"python","filename":"qc3scripts/myscript.pys","value":"from qcontrol3.server.script import Script\nfrom qcontrol3.tools.units import u\nfrom config.devices import ScriptDevices\n\niter_list = [1, 2, 3, 4]\nclass MyScript(Script):\n   def __init__(self):\n        super().__init__()\n        self.devices = ScriptDevices()\n\n    def main(self):\n        time = 10.0 * u.ms  # absolute deadtime for Adwin sequencer\n        self.devices.molasse_shutter.add_pulse(time, duration = (1 + iter_step) * 10 * u.ms)\n        time += 220 * u.ms\n        self.mot_aom.ramp_to(time, 2 * u.V, duration = 100 * u.ms)\ntiming_script = MyScript()","key":"MLhRSBdQen"},{"type":"caption","children":[{"type":"paragraph","children":[{"type":"captionNumber","kind":"code","label":"qc3script-level1","identifier":"qc3script-level1","html_id":"qc3script-level1","enumerator":"6","children":[{"type":"text","value":"Code ","key":"hjcw4e9dEn"},{"type":"text","value":"6","key":"JZoGHdQ2lP"},{"type":"text","value":":","key":"WuajlVR2T2"}],"template":"Code %s:","key":"Rh4fEodzOa"},{"type":"text","value":"A script that is a bit more evaluate than the previous one. Devices are imported from an other file with a more ","position":{"start":{"line":256,"column":1},"end":{"line":256,"column":1}},"key":"rJo2DdQ2uM"},{"type":"emphasis","position":{"start":{"line":256,"column":1},"end":{"line":256,"column":1}},"children":[{"type":"text","value":"user-friendly","position":{"start":{"line":256,"column":1},"end":{"line":256,"column":1}},"key":"ua2fzdedwd"}],"key":"AJVzaLsF7b"},{"type":"text","value":" name and with other methods than the ","position":{"start":{"line":256,"column":1},"end":{"line":256,"column":1}},"key":"cmUMiPt9XY"},{"type":"inlineCode","value":"add","position":{"start":{"line":256,"column":1},"end":{"line":256,"column":1}},"key":"E2l2ekj40a"},{"type":"text","value":" one.  For example, the mot_aom use the ramp_to method and one could imagine objects with other methods (exponential ramps for example).","position":{"start":{"line":256,"column":1},"end":{"line":256,"column":1}},"key":"Bdn2Bqq6AG"}],"key":"vsEzSuzAsw"}],"key":"wVTvgprXZ1"}],"enumerator":"6","html_id":"qc3script-level1","key":"dND8YH1M1y"},{"type":"admonition","kind":"tip","children":[{"type":"admonitionTitle","children":[{"type":"emphasis","position":{"start":{"line":276,"column":1},"end":{"line":276,"column":1}},"children":[{"type":"text","value":"Summary","position":{"start":{"line":276,"column":1},"end":{"line":276,"column":1}},"key":"ZvGpiGqHqo"}],"key":"afS25liBOa"}],"key":"wPm94KV0au"},{"type":"paragraph","position":{"start":{"line":277,"column":1},"end":{"line":277,"column":1}},"children":[{"type":"text","value":"In summary, in this section, we learned how to declare user channels from already defined timing channels and how to modify their values using the server (live) or in a script (at specific times). In the next section, we will explore creating timing channels and their associated timing devices.","position":{"start":{"line":277,"column":1},"end":{"line":277,"column":1}},"key":"eYlFFCdLYS"}],"key":"OV1vrQ0WPf"}],"key":"DeMbBB7eam"},{"type":"heading","depth":2,"position":{"start":{"line":282,"column":1},"end":{"line":282,"column":1}},"children":[{"type":"text","value":"Remote server and drivers","position":{"start":{"line":282,"column":1},"end":{"line":282,"column":1}},"key":"FShyQgKqiG"}],"identifier":"section-remote","label":"section-remote","html_id":"section-remote","enumerator":"3","key":"YatJ3dgTsM"},{"type":"paragraph","position":{"start":{"line":284,"column":1},"end":{"line":284,"column":1}},"children":[{"type":"text","value":"Often, in a cold atom experiment, one needs to use several other instruments, for example waveform generators or cameras. In QControl, commands are sent at various time during a task, offering the possibility to use one instrument in two different configurations during a run or to assign a value at an instrument after having perform a measurement within the same task.","position":{"start":{"line":284,"column":1},"end":{"line":284,"column":1}},"key":"zSpVaVHO2u"}],"key":"PCdSkkhIir"},{"type":"container","kind":"figure","identifier":"remotes","label":"remotes","children":[{"type":"image","url":"/~gondret/phd_manuscript/build/remotes-2d4d5841ead0888a57a71f927871be61.png","alt":"Scheme of the different remotes used in a cold atoms experiment.","width":"100%","align":"center","key":"ZuoZfyxad5","urlSource":"images/remotes.png","urlOptimized":"/~gondret/phd_manuscript/build/remotes-2d4d5841ead0888a57a71f927871be61.webp"},{"type":"caption","children":[{"type":"paragraph","position":{"start":{"line":290,"column":1},"end":{"line":290,"column":1}},"children":[{"type":"captionNumber","kind":"figure","label":"remotes","identifier":"remotes","html_id":"remotes","enumerator":"2","children":[{"type":"text","value":"Figure ","key":"B8tYNTMf3Z"},{"type":"text","value":"2","key":"Udlqw6gig3"},{"type":"text","value":":","key":"q2UW2BiiFh"}],"template":"Figure %s:","key":"GRJ3piMNAY"},{"type":"text","value":"This scheme is a specific zoom of ","position":{"start":{"line":290,"column":1},"end":{"line":290,"column":1}},"key":"ia6zrDY0Gi"},{"type":"crossReference","position":{"start":{"line":290,"column":1},"end":{"line":290,"column":1}},"children":[{"type":"text","value":"Figure ","key":"yymU675fom"},{"type":"text","value":"1","key":"yx3jEgwmux"}],"identifier":"qcontrol-timing-system","label":"qcontrol-timing-system","kind":"figure","template":"Figure %s","enumerator":"1","resolved":true,"html_id":"qcontrol-timing-system","key":"N8u5FkDfPq"},{"type":"text","value":" on the different Timing Controllers. Before launching the client, the user must start all remote server that host the remote timing controllers. When a run is about to start, the timing system provides timing controllers its list of events and then launch the ","position":{"start":{"line":290,"column":1},"end":{"line":290,"column":1}},"key":"XEyYmP8Pw3"},{"type":"emphasis","position":{"start":{"line":290,"column":1},"end":{"line":290,"column":1}},"children":[{"type":"text","value":"official start signal","position":{"start":{"line":290,"column":1},"end":{"line":290,"column":1}},"key":"EjTbNCxVMK"}],"key":"fLXj8Vsqdz"},{"type":"text","value":". Until the end of the run, each remote timing uses its own clock as time reference, based on the starting signal. On this scheme, this is underlined by each remote timing controller represented as shells of the computer. The sequencer clock is of course internal and set as the ","position":{"start":{"line":290,"column":1},"end":{"line":290,"column":1}},"key":"O2dmTjwGCM"},{"type":"emphasis","position":{"start":{"line":290,"column":1},"end":{"line":290,"column":1}},"children":[{"type":"text","value":"master timing controller","position":{"start":{"line":290,"column":1},"end":{"line":290,"column":1}},"key":"unrdjE1Bnx"}],"key":"CUTJ2otrGe"},{"type":"text","value":" in the ","position":{"start":{"line":290,"column":1},"end":{"line":290,"column":1}},"key":"AalOmLeTTo"},{"type":"inlineCode","value":"qc3cripts/config/hardware.py","position":{"start":{"line":290,"column":1},"end":{"line":290,"column":1}},"key":"VijFpqDsZj"},{"type":"text","value":" file.  The link between timing device as waveform generators or oscilloscopes are defined in each remote configuration file. Note also that the name of each remote (","position":{"start":{"line":290,"column":1},"end":{"line":290,"column":1}},"key":"QWAT3vf0ia"},{"type":"inlineCode","value":"REMOTE1","position":{"start":{"line":290,"column":1},"end":{"line":290,"column":1}},"key":"Z4oaXfwUfi"},{"type":"text","value":" for example) and their location (the folder that contains the ","position":{"start":{"line":290,"column":1},"end":{"line":290,"column":1}},"key":"NHdzi92AKJ"},{"type":"inlineCode","value":"config.py","position":{"start":{"line":290,"column":1},"end":{"line":290,"column":1}},"key":"QOZYpmiubS"},{"type":"text","value":" file) must be declared in the qcontrol configuration file (in ","position":{"start":{"line":290,"column":1},"end":{"line":290,"column":1}},"key":"SyKfZRp97o"},{"type":"inlineCode","value":"~/.qc3","position":{"start":{"line":290,"column":1},"end":{"line":290,"column":1}},"key":"MSl7DmPqkT"},{"type":"text","value":" on linux).","position":{"start":{"line":290,"column":1},"end":{"line":290,"column":1}},"key":"D1y0hBeqo3"}],"key":"iBeEsM7W5Q"}],"key":"szkmjOI9aW"}],"enumerator":"2","html_id":"remotes","key":"uwSUjknVmg"},{"type":"heading","depth":3,"position":{"start":{"line":293,"column":1},"end":{"line":293,"column":1}},"children":[{"type":"text","value":"The remote server","position":{"start":{"line":293,"column":1},"end":{"line":293,"column":1}},"key":"okc2rb7fJY"}],"identifier":"the-remote-server","label":"The remote server","html_id":"the-remote-server","implicit":true,"key":"rNyFKw7r5V"},{"type":"paragraph","position":{"start":{"line":294,"column":1},"end":{"line":294,"column":1}},"children":[{"type":"text","value":"As shown in ","position":{"start":{"line":294,"column":1},"end":{"line":294,"column":1}},"key":"LU11pWqa0O"},{"type":"crossReference","position":{"start":{"line":294,"column":1},"end":{"line":294,"column":1}},"children":[{"type":"text","value":"Figure ","key":"CZxi3L8axZ"},{"type":"text","value":"1","key":"VDgcxVsMMx"}],"identifier":"qcontrol-timing-system","label":"qcontrol-timing-system","kind":"figure","template":"Figure %s","enumerator":"1","resolved":true,"html_id":"qcontrol-timing-system","key":"jbhLMcpiDa"},{"type":"text","value":", timing devices are controlled by the software controller. The command","position":{"start":{"line":294,"column":1},"end":{"line":294,"column":1}},"key":"xFpiN4Be65"}],"key":"rsqLWMjGlk"},{"type":"code","lang":"shell","value":"$ qcontrol3-remoteserver REMOTE0","key":"PJxOejXATW"},{"type":"paragraph","position":{"start":{"line":299,"column":1},"end":{"line":300,"column":1}},"children":[{"type":"text","value":"starts the ","position":{"start":{"line":299,"column":1},"end":{"line":299,"column":1}},"key":"u7oRzcGqyk"},{"type":"link","url":"https://gitlab.in2p3.fr/gaz-quantiques-lcf/helium-1/qcontrol3_driver_timing_softwareremote/-/blob/master/qcontrol3/driver/timing/softwareremote/remoteserver.py","position":{"start":{"line":299,"column":1},"end":{"line":299,"column":1}},"children":[{"type":"text","value":"remote server","position":{"start":{"line":299,"column":1},"end":{"line":299,"column":1}},"key":"Q5w7rXJoqZ"}],"urlSource":"https://gitlab.in2p3.fr/gaz-quantiques-lcf/helium-1/qcontrol3_driver_timing_softwareremote/-/blob/master/qcontrol3/driver/timing/softwareremote/remoteserver.py","key":"WDNm11EEgk"},{"type":"text","value":" which can be seen as the actual ","position":{"start":{"line":299,"column":1},"end":{"line":299,"column":1}},"key":"KaunW3Ywub"},{"type":"link","url":"https://gitlab.in2p3.fr/gaz-quantiques-lcf/helium-1/qcontrol3_driver_timing_softwareremote/-/blob/master/qcontrol3/driver/timing/softwareremote/remotecontroller.py","position":{"start":{"line":299,"column":1},"end":{"line":299,"column":1}},"children":[{"type":"text","value":"remote controller","position":{"start":{"line":299,"column":1},"end":{"line":299,"column":1}},"key":"gfxqWl5qN8"}],"urlSource":"https://gitlab.in2p3.fr/gaz-quantiques-lcf/helium-1/qcontrol3_driver_timing_softwareremote/-/blob/master/qcontrol3/driver/timing/softwareremote/remotecontroller.py","key":"uIFxl6UfLF"},{"type":"text","value":". Launching this command for the first time should create a ","position":{"start":{"line":299,"column":1},"end":{"line":299,"column":1}},"key":"chgH75r86l"},{"type":"inlineCode","value":"qc3remotecontroller0","position":{"start":{"line":299,"column":1},"end":{"line":299,"column":1}},"key":"sFoDmUcXrc"},{"type":"text","value":" in your home path. Remote devices of your experiment should be declared in the ","position":{"start":{"line":299,"column":1},"end":{"line":299,"column":1}},"key":"nEAlujdtcu"},{"type":"inlineCode","value":"config.py","position":{"start":{"line":299,"column":1},"end":{"line":299,"column":1}},"key":"Q9Maxkph7N"},{"type":"text","value":" file of this folder","position":{"start":{"line":299,"column":1},"end":{"line":299,"column":1}},"key":"FaWK5FqMYV"},{"type":"footnoteReference","identifier":"6","label":"6","position":{"start":{"line":299,"column":1},"end":{"line":299,"column":1}},"number":6,"enumerator":"6","key":"reRi7z0GeB"},{"type":"text","value":". Note that the hardware properties of your instrument must be filled in this file : for example, instrument that use the VISA standard communication protocol can be controlled with an existing ","position":{"start":{"line":299,"column":1},"end":{"line":299,"column":1}},"key":"YYLhC1QqZc"},{"type":"link","url":"https://gitlab.in2p3.fr/gaz-quantiques-lcf/helium-1/qcontrol3_driver_protocol_visa","position":{"start":{"line":299,"column":1},"end":{"line":299,"column":1}},"children":[{"type":"text","value":"VISA driver class","position":{"start":{"line":299,"column":1},"end":{"line":299,"column":1}},"key":"bJHzMZBMSW"}],"urlSource":"https://gitlab.in2p3.fr/gaz-quantiques-lcf/helium-1/qcontrol3_driver_protocol_visa","key":"rp9FQlAexp"},{"type":"text","value":".\nSince this remote class can be used for several instruments, it is in the ","position":{"start":{"line":299,"column":1},"end":{"line":299,"column":1}},"key":"h88kYU03oZ"},{"type":"inlineCode","value":"config.py","position":{"start":{"line":299,"column":1},"end":{"line":299,"column":1}},"key":"bwEzJciNZv"},{"type":"text","value":" file that the user fills hardware informations such as the IP address, its name and other properties (timeout, encoding...). Even though various drivers already exist, it is often needed to create a new remote device. In the following, we will see how to create a simple driver from scratch.","position":{"start":{"line":299,"column":1},"end":{"line":299,"column":1}},"key":"PIp1SL9MTG"}],"key":"v3UNtCFqgN"},{"type":"heading","depth":3,"position":{"start":{"line":302,"column":1},"end":{"line":302,"column":1}},"children":[{"type":"text","value":"Creating a remote driver","position":{"start":{"line":302,"column":1},"end":{"line":302,"column":1}},"key":"q7BspkCK7T"}],"identifier":"creating-a-remote-driver","label":"Creating a remote driver","html_id":"creating-a-remote-driver","implicit":true,"key":"gavO0p9rrh"},{"type":"paragraph","position":{"start":{"line":303,"column":1},"end":{"line":303,"column":1}},"children":[{"type":"text","value":"In this section, we will create a device that will query a database to print in the terminal the meteo in a city (provided by the user) at a precised time. To do so, we need a string timing channel so that the user can set the city and a boolean channel such that when set to ","position":{"start":{"line":303,"column":1},"end":{"line":303,"column":1}},"key":"a5xBQow9UQ"},{"type":"inlineCode","value":"True","position":{"start":{"line":303,"column":1},"end":{"line":303,"column":1}},"key":"gfyao9NWQn"},{"type":"text","value":", the device prompt the meteo to the database and print it.","position":{"start":{"line":303,"column":1},"end":{"line":303,"column":1}},"key":"Be5fQVrNrE"}],"key":"FbHslcM9rE"},{"type":"paragraph","position":{"start":{"line":305,"column":1},"end":{"line":305,"column":1}},"children":[{"type":"text","value":"In QControl, remote drivers consist of a python package that should respect the QControl3 package tree. To ensure that, we will use the dedicated command","position":{"start":{"line":305,"column":1},"end":{"line":305,"column":1}},"key":"ywKSqybUI7"}],"key":"zHYdyi36s1"},{"type":"code","lang":"shell","value":"$ qcontrol3-create-package","key":"sJ6fFYeygd"},{"type":"paragraph","position":{"start":{"line":311,"column":1},"end":{"line":312,"column":1}},"children":[{"type":"text","value":"in which you will have to fill the type of package you want to create, its name and description. This creates a new directory on your computer that contains the relevant file tree as well as a git repository. A ","position":{"start":{"line":311,"column":1},"end":{"line":311,"column":1}},"key":"dLIvzAAexv"},{"type":"inlineCode","value":"setup.py","position":{"start":{"line":311,"column":1},"end":{"line":311,"column":1}},"key":"YkfAFEEcTb"},{"type":"text","value":" file is also created to install it in your python\nenvironment","position":{"start":{"line":311,"column":1},"end":{"line":311,"column":1}},"key":"h2u36EZD6m"},{"type":"footnoteReference","identifier":"7","label":"7","position":{"start":{"line":311,"column":1},"end":{"line":311,"column":1}},"number":7,"enumerator":"7","key":"YD1HHudsx9"},{"type":"text","value":". Since we want to create a meteo driver, we will create in the following ","position":{"start":{"line":311,"column":1},"end":{"line":311,"column":1}},"key":"iN8UVOg6Xa"},{"type":"emphasis","position":{"start":{"line":311,"column":1},"end":{"line":311,"column":1}},"children":[{"type":"text","value":"misc","position":{"start":{"line":311,"column":1},"end":{"line":311,"column":1}},"key":"werWBsFDHg"}],"key":"OhVgKYg7Dy"},{"type":"text","value":" package named ","position":{"start":{"line":311,"column":1},"end":{"line":311,"column":1}},"key":"eGnZRn4lcG"},{"type":"inlineCode","value":"meteo_driver.py","position":{"start":{"line":311,"column":1},"end":{"line":311,"column":1}},"key":"bDS4nhMmkN"},{"type":"text","value":".","position":{"start":{"line":311,"column":1},"end":{"line":311,"column":1}},"key":"fAFkIULzDX"}],"key":"hno9IK6mFh"},{"type":"comment","value":"  The driver will consist of two timing channels:\n\n-   one channel of type string through which the user will give the name of the city from which he wants the meteo,\n\n-   one channel of type boolean that prompt the database when set to `True`. ","key":"x2X3mhUzcW"},{"type":"paragraph","position":{"start":{"line":319,"column":1},"end":{"line":320,"column":1}},"children":[{"type":"text","value":"The ","position":{"start":{"line":319,"column":1},"end":{"line":319,"column":1}},"key":"EqFZmOZPqw"},{"type":"crossReference","position":{"start":{"line":319,"column":1},"end":{"line":319,"column":1}},"children":[{"type":"text","value":"Figure ","key":"lprqLhkDRJ"},{"type":"text","value":"3","key":"lJSFlUgBEP"}],"identifier":"remote_links","label":"remote_links","kind":"figure","template":"Figure %s","enumerator":"3","resolved":true,"html_id":"remote-links","key":"NxifFe4gx4"},{"type":"text","value":" tries to summarize the links\nbetween the two software devices that compose a diver defined in ","position":{"start":{"line":319,"column":1},"end":{"line":319,"column":1}},"key":"mwCLkcNhMF"},{"type":"crossReference","position":{"start":{"line":319,"column":1},"end":{"line":319,"column":1}},"children":[{"type":"text","value":"Program ","key":"fKPlz5a3b6"},{"type":"text","value":"7","key":"rDlfReQ8OM"}],"identifier":"driver-complete-example","label":"driver-complete-example","kind":"code","template":"Program %s","enumerator":"7","resolved":true,"html_id":"driver-complete-example","key":"PpGwo6NPAB"},{"type":"text","value":". The upper part of the later sets up the client part of the driver : the ","position":{"start":{"line":319,"column":1},"end":{"line":319,"column":1}},"key":"FDJ2l102bx"},{"type":"inlineCode","value":"MeteoDevice","position":{"start":{"line":319,"column":1},"end":{"line":319,"column":1}},"key":"xJadKecBZI"},{"type":"text","value":" class defined in the driver is a Software Device composed of two String type and Boolean type timing channels whose names are respectively ","position":{"start":{"line":319,"column":1},"end":{"line":319,"column":1}},"key":"eCDCkfiYgd"},{"type":"inlineCode","value":"LOCATION","position":{"start":{"line":319,"column":1},"end":{"line":319,"column":1}},"key":"ny2xdNfGQa"},{"type":"text","value":" and ","position":{"start":{"line":319,"column":1},"end":{"line":319,"column":1}},"key":"CwMqZq9X8K"},{"type":"inlineCode","value":"TRIGGER","position":{"start":{"line":319,"column":1},"end":{"line":319,"column":1}},"key":"cQIm237pWq"},{"type":"text","value":". Nothing is implemented in this part since they are just used to assign the value set by the user to the remote device. Indeed, one can see that timing channels that are children of the ","position":{"start":{"line":319,"column":1},"end":{"line":319,"column":1}},"key":"Fyecbh1BcE"},{"type":"inlineCode","value":"MeteoDevice","position":{"start":{"line":319,"column":1},"end":{"line":319,"column":1}},"key":"DTuo7B6lYh"},{"type":"text","value":" inherit from ","position":{"start":{"line":319,"column":1},"end":{"line":319,"column":1}},"key":"gQ5sLAIUaD"},{"type":"inlineCode","value":"SoftwareTimingChannel","position":{"start":{"line":319,"column":1},"end":{"line":319,"column":1}},"key":"pymcwcpWAJ"},{"type":"text","value":" class and not from ","position":{"start":{"line":319,"column":1},"end":{"line":319,"column":1}},"key":"KjM2HYHk7s"},{"type":"inlineCode","value":"TimingChannel","position":{"start":{"line":319,"column":1},"end":{"line":319,"column":1}},"key":"gv69IBjAe2"},{"type":"text","value":".","position":{"start":{"line":319,"column":1},"end":{"line":319,"column":1}},"key":"mHrFYTY59B"}],"key":"dCLiiriZZi"},{"type":"paragraph","position":{"start":{"line":322,"column":1},"end":{"line":322,"column":1}},"children":[{"type":"text","value":"The second part of the code defines the remote part and the ","position":{"start":{"line":322,"column":1},"end":{"line":322,"column":1}},"key":"ccwkn2SFiH"},{"type":"inlineCode","value":"RemoteMeteoDevice","position":{"start":{"line":322,"column":1},"end":{"line":322,"column":1}},"key":"B2C0EPJhSV"},{"type":"text","value":" class. This class has also two timing channels as children whose name are also ","position":{"start":{"line":322,"column":1},"end":{"line":322,"column":1}},"key":"nKdwKBSrFw"},{"type":"inlineCode","value":"SCRIPT_ADDRESS","position":{"start":{"line":322,"column":1},"end":{"line":322,"column":1}},"key":"Vo6Y7VPkGA"},{"type":"text","value":" and ","position":{"start":{"line":322,"column":1},"end":{"line":322,"column":1}},"key":"PxR5LaDfsK"},{"type":"inlineCode","value":"TRIGGER","position":{"start":{"line":322,"column":1},"end":{"line":322,"column":1}},"key":"zzeEmaehV8"},{"type":"text","value":". Classes that define those children inherit from the ","position":{"start":{"line":322,"column":1},"end":{"line":322,"column":1}},"key":"pKNGmdVWAt"},{"type":"inlineCode","value":"TimingChannel","position":{"start":{"line":322,"column":1},"end":{"line":322,"column":1}},"key":"IVmVmHEKGm"},{"type":"text","value":" class. Whenever one channel value of the (client) software device is changed, the value of the associated remote timing channel is modified too through the “","position":{"start":{"line":322,"column":1},"end":{"line":322,"column":1}},"key":"l67MdUi4g6"},{"type":"inlineCode","value":"set_value_raw","position":{"start":{"line":322,"column":1},"end":{"line":322,"column":1}},"key":"cYrmZyWUWA"},{"type":"text","value":"” method. Note that this correspondence is only possible if the names of each channel are identical. In the example, both the children of the ","position":{"start":{"line":322,"column":1},"end":{"line":322,"column":1}},"key":"adjpIFjqsY"},{"type":"inlineCode","value":"MeteoDevice","position":{"start":{"line":322,"column":1},"end":{"line":322,"column":1}},"key":"bajv4OQLE6"},{"type":"text","value":" and the ","position":{"start":{"line":322,"column":1},"end":{"line":322,"column":1}},"key":"wujRRJV092"},{"type":"inlineCode","value":"RemoteMeteoDevice","position":{"start":{"line":322,"column":1},"end":{"line":322,"column":1}},"key":"sMGuRGCMP8"},{"type":"text","value":" have the same name - ","position":{"start":{"line":322,"column":1},"end":{"line":322,"column":1}},"key":"oy0HAZkF5f"},{"type":"inlineCode","value":"METEO_NAME.TRIGGER","position":{"start":{"line":322,"column":1},"end":{"line":322,"column":1}},"key":"MVLMHNI9PX"},{"type":"text","value":" for example. When a channel is modified, the ","position":{"start":{"line":322,"column":1},"end":{"line":322,"column":1}},"key":"RUnLLyGQAl"},{"type":"inlineCode","value":"io_update","position":{"start":{"line":322,"column":1},"end":{"line":322,"column":1}},"key":"ABXgaLihDP"},{"type":"text","value":" method of its parent is also called, which can be view as callback. Note also that a software device can retrieve the value of its children channels through its “","position":{"start":{"line":322,"column":1},"end":{"line":322,"column":1}},"key":"dCJKujBUb9"},{"type":"inlineCode","value":"children","position":{"start":{"line":322,"column":1},"end":{"line":322,"column":1}},"key":"cJ4AgFyqqb"},{"type":"text","value":"” dictionary attribute. In our driver, we therefore use the  ","position":{"start":{"line":322,"column":1},"end":{"line":322,"column":1}},"key":"zX7tughE8R"},{"type":"inlineCode","value":"io_update","position":{"start":{"line":322,"column":1},"end":{"line":322,"column":1}},"key":"KfldG6YNOj"},{"type":"text","value":" method : given that the default value of the trigger channel is False, whenever its value is set to True, the driver get the meteo from the location.","position":{"start":{"line":322,"column":1},"end":{"line":322,"column":1}},"key":"QTSpAnAttx"}],"key":"QZYvjK92Xr"},{"type":"container","kind":"figure","identifier":"remote_links","label":"remote_links","children":[{"type":"image","url":"/~gondret/phd_manuscript/build/qc3_remote_links-13ce773cd52c7e21b5f42538a0b50c8a.png","alt":"Scheme of the QControl3 timing system","width":"100%","align":"center","key":"ZOynYdngkf","urlSource":"images/qc3_remote_links.png","urlOptimized":"/~gondret/phd_manuscript/build/qc3_remote_links-13ce773cd52c7e21b5f42538a0b50c8a.webp"},{"type":"caption","children":[{"type":"paragraph","position":{"start":{"line":329,"column":1},"end":{"line":329,"column":1}},"children":[{"type":"captionNumber","kind":"figure","label":"remote_links","identifier":"remote_links","html_id":"remote-links","enumerator":"3","children":[{"type":"text","value":"Figure ","key":"d1ue4YeYCu"},{"type":"text","value":"3","key":"TFwr8R8wz9"},{"type":"text","value":":","key":"Pkl2n7W1ZF"}],"template":"Figure %s:","key":"mEz6BVONCy"},{"type":"text","value":"This scheme is a zoom from ","position":{"start":{"line":329,"column":1},"end":{"line":329,"column":1}},"key":"LnpxoRWYYH"},{"type":"crossReference","position":{"start":{"line":329,"column":1},"end":{"line":329,"column":1}},"children":[{"type":"text","value":"Figure ","key":"vSCGt6myV5"},{"type":"text","value":"1","key":"QdFiL7fHtt"}],"identifier":"qcontrol-timing-system","label":"qcontrol-timing-system","kind":"figure","template":"Figure %s","enumerator":"1","resolved":true,"html_id":"qcontrol-timing-system","key":"IHntloA2rC"},{"type":"text","value":" on the specific driver ","position":{"start":{"line":329,"column":1},"end":{"line":329,"column":1}},"key":"S2jZy83pfr"},{"type":"inlineCode","value":"meteo_driver.py","position":{"start":{"line":329,"column":1},"end":{"line":329,"column":1}},"key":"v2vmJxMiau"},{"type":"text","value":". Relation between objects are represented by lines : solid for child/parent relation, dashes for user channels and dotted for others. Next to each line is given the file in which the relation must be set. Each frame contains the description of the object with its name of the associated node, the object description in QControl3 language, the name of the class and the class the object inherits from (see legend). The driver is composed of two software devices one being the remote part (green) and one the client part (brown). In the driver file are defined the two times two timing channels that compose the driver : two are children of the remote part of the driver and the two other are channels of the client part. The user creates user channels associated to those timing channels : changing a channel value - on the client side - sends an update on the remote side through the communication channel between the ","position":{"start":{"line":329,"column":1},"end":{"line":329,"column":1}},"key":"enpRamHrWy"},{"type":"link","url":"https://gitlab.in2p3.fr/gaz-quantiques-lcf/helium-1/qcontrol3_driver_timing_softwareremote/qcontrol3/driver/timing/softwareremote/softwarecontroller.py","position":{"start":{"line":329,"column":1},"end":{"line":329,"column":1}},"children":[{"type":"text","value":"Remote Software Controller","position":{"start":{"line":329,"column":1},"end":{"line":329,"column":1}},"key":"Sm5mtJCoLv"}],"urlSource":"https://gitlab.in2p3.fr/gaz-quantiques-lcf/helium-1/qcontrol3_driver_timing_softwareremote/qcontrol3/driver/timing/softwareremote/softwarecontroller.py","key":"oKDp4M5QJl"},{"type":"text","value":" and the Remote Controller. This is made possible if the two names coincide.","position":{"start":{"line":329,"column":1},"end":{"line":329,"column":1}},"key":"ZgjXBnZuUp"}],"key":"TMcIvNi7RN"}],"key":"cfOToifIYe"}],"enumerator":"3","html_id":"remote-links","key":"HteQVrEREt"},{"type":"container","kind":"code","label":"driver-complete-example","identifier":"driver-complete-example","children":[{"type":"code","lang":"python","filename":"meteo_driver.py","value":"This code is not available on PDF.","key":"lnLH5FwWii"},{"type":"caption","children":[{"type":"paragraph","children":[{"type":"captionNumber","kind":"code","label":"driver-complete-example","identifier":"driver-complete-example","html_id":"driver-complete-example","enumerator":"7","children":[{"type":"text","value":"Code ","key":"Y8eNCUAbH5"},{"type":"text","value":"7","key":"gBVpurIItC"},{"type":"text","value":":","key":"nnXhAYXFRU"}],"template":"Code %s:","key":"ZimwLXjoko"},{"type":"text","value":"The meteo_device example. This code creates the links between the mete_devices and its timing channels. The brown part of ","position":{"start":{"line":334,"column":1},"end":{"line":334,"column":1}},"key":"VmfAEdPRDd"},{"type":"crossReference","position":{"start":{"line":334,"column":1},"end":{"line":334,"column":1}},"children":[{"type":"text","value":"Figure ","key":"VFxJBYrVjv"},{"type":"text","value":"3","key":"eVpTA6ZJzC"}],"identifier":"remote_links","label":"remote_links","kind":"figure","template":"Figure %s","enumerator":"3","resolved":true,"html_id":"remote-links","key":"eatP755u8U"},{"type":"text","value":" is the local part of the driver with which the user will communicate. The green part of the driver is in the second part of the code : the remote part. See text for more description.","position":{"start":{"line":334,"column":1},"end":{"line":334,"column":1}},"key":"IuPGMFH7vb"}],"key":"ngHKTcdV0r"}],"key":"h6cTeVTEjm"}],"enumerator":"7","html_id":"driver-complete-example","key":"X47sUS3m51"},{"type":"comment","value":" \n```{code} python\n:name: driver-complete-example\n:caption: The meteo_device example. This code creates the links between the mete_devices and its timing channels. The brown part of [](#remote_links) is the local part of the driver with which the user will communicate. The green part of the driver is in the second part of the code : the remote part. See text for more descripion.\n:filename: meteo_driver.py\n\nfrom qcontrol3.driver.timing.softwareremote import softwaredevice, softwarechannel\nfrom qcontrol3.server import timingchannel\nfrom qcontrol3.tools import logsetup\nfrom qcontrol3.tools.units import u\nimport os, requests\n\nlog = logsetup.getlogger(\"driverlogger\")\n\n\n# ---------------------- LOCAL ------------------------\n# ------------- no customization needed ---------------\n\nclass MeteoDevice(softwaredevice.SoftwareDevice):\n    def __init__(self, name=\"METEO_NAME\", description=\"\"):\n        super().__init__(name, description)\n        self.add_child(LocationChannel())\n        self.add_child(TriggerChannel())\n\n\nclass LocationChannel(softwarechannel.SoftwareTimingChannelString):\n    def __init__(\n        self, name=\"LOCATION\",\n        description=\"From which place do you want meteo.\",\n        default_value = \"Paris\"\n    ):\n        super().__init__(name, description, 0 * u.s, default_value, 1000, \"utf-8\")\n\n\nclass TriggerChannel(softwarechannel.SoftwareTimingChannelBool):\n    def __init__(self, \n                 name=\"TRIGGER\",\n                 description=\"Get the weather when set to True\",\n                 default_value = False):\n        super().__init__(name, description, 0 * u.s, default_value)\n\n\n# ---------------------- REMOTE ------------------------\n# ------------ stuff is implemented here ---------------\n\nclass RemoteMeteoDevice(softwaredevice.SoftwareDevice):\n    def __init__(\n        self,\n        name=\"METEO_NAME\",\n        description=\"A meteo timing device\",\n        deadtime=0 * u.s,\n        own_thread=False,\n        url_adress = \"www.meteo_name.com/database\"\n    ):\n        super().__init__(name, description, deadtime, own_thread)\n        self.url_adress = url_adress\n        self._channel_setup()\n\n    def _channel_setup(self):\n        self.add_child(RemoteLocationChannel())\n        self.add_child(RemoteTriggerChannel())\n\n    def io_update(self): \n        # function executed each time a children channel value is changed. \n        print(f\"IO_UPDATE on {self.name}\")\n        if self.children[\"TRIGGER\"].get_value_raw() is True:\n            location = self.children[\"LOCATION\"]\n            temperature = self.get_meteo(location)\n            print(f\"Temperature in {location} is {temperature} °C.\")\n\n    def get_meteo(self, location = \"Paris\"):\n        # return the temperature from at location querying url_adress \n        url = f\"{self.url_adress}/weather?q={location}\"\n        try:\n            data = requests.get(url).json()\n            return data[\"main\"][\"temp\"]\n        except Exception as e:\n            log.error(f\"Failed to get the temperature. I assume it is cold. {e}\")\n            return 0\n\nclass RemoteLocationChannel(timingchannel.TimingChannelString):\n    def __init__(self, name=\"LOCATION\", description=\"...\"):\n        super().__init__(name, description, 0 * u.s, \"hello\", 1000, \"utf-8\")\n\n    def set_value_raw(self, value):\n        # Execute the command that sets the channel value here.\n        log.info(\"{} sets the value {}.\".format(self.full_name, value))\n        self.value = value\n\n    def get_value_raw(self):\n        # Execute the command that gets the channel value here.\n        log.info(\"{} reads its value.\".format(self.full_name))\n        return self.value\n\nclass RemoteTriggerChannel(timingchannel.TimingChannelBool):\n    def __init__(self, name=\"TRIGGER\", description=\"...\"):\n        super().__init__(name, description, 0 * u.s, False)\n\n    def set_value_raw(self, value):\n        # Execute the command that sets the channel value here.\n        log.info(\"{} sets the value {}.\".format(self.full_name, value))\n        self.value = value\n\n    def get_value_raw(self):\n        # Execute the command that gets the channel value here.\n        log.info(\"{} reads its value.\".format(self.full_name))\n        return self.value\n```\n ","key":"j0uqh7bl0r"},{"type":"paragraph","position":{"start":{"line":453,"column":1},"end":{"line":453,"column":1}},"children":[{"type":"text","value":"Once your file driver is ready, the driver must be declared as a timing device on both remote and client parts. The remote part must be set up in the ","position":{"start":{"line":453,"column":1},"end":{"line":453,"column":1}},"key":"WkoSoGn0ff"},{"type":"inlineCode","value":"config","position":{"start":{"line":453,"column":1},"end":{"line":453,"column":1}},"key":"ltLpRd57gx"},{"type":"text","value":" file of the remote controller repository","position":{"start":{"line":453,"column":1},"end":{"line":453,"column":1}},"key":"ZjsgFCOxzL"},{"type":"footnoteReference","identifier":"9","label":"9","position":{"start":{"line":453,"column":1},"end":{"line":453,"column":1}},"number":9,"enumerator":"9","key":"qSK41B9TiP"},{"type":"text","value":" while the client part should be set up in the ","position":{"start":{"line":453,"column":1},"end":{"line":453,"column":1}},"key":"jTELvp62tW"},{"type":"inlineCode","value":"hardware","position":{"start":{"line":453,"column":1},"end":{"line":453,"column":1}},"key":"Wx2MXpijHI"},{"type":"text","value":" file of the configuration script folder.","position":{"start":{"line":453,"column":1},"end":{"line":453,"column":1}},"key":"ffF2gkrdaP"}],"key":"UeZXg5699E"},{"type":"paragraph","position":{"start":{"line":455,"column":1},"end":{"line":455,"column":1}},"children":[{"type":"text","value":"We first declare the remote part of the device, in this case in the config file of the remote0 directory. Since we want to provide the meteo from to different website, we create two drivers whose name and url addresses are different. Note that the name define here define the name of the timing channel, for example here, one of the timing channel name is ","position":{"start":{"line":455,"column":1},"end":{"line":455,"column":1}},"key":"NfpIPQOVUV"},{"type":"inlineCode","value":"REMOTE0.METEO_CIEL.TRIGGER","position":{"start":{"line":455,"column":1},"end":{"line":455,"column":1}},"key":"v7uALcYnnj"},{"type":"text","value":".","position":{"start":{"line":455,"column":1},"end":{"line":455,"column":1}},"key":"EgfcHw3KiU"}],"key":"PCvZK1pCjo"},{"type":"container","kind":"code","label":"remote-device-declaration-config","identifier":"remote-device-declaration-config","children":[{"type":"code","lang":"python","value":"#file : config.py\nfrom qcontrol3.driver.misc.meteo_driver import RemoteMeteoDevice\ndef hardware_setup(remote_controller):\n    # 1. instantiate device \n    dev1 = RemoteMeteoDevice(name = \"METEO_CIEL\", \n                            description= \"query meteo to meteo-ciel.com\",\n                            url_adress = \"www.meteo-ciel.com/database\")\n    # 2. add it to the remote_controller \n    remote_controller.add_child(dev1)\n\n    dev2 = RemoteMeteoDevice(name = \"METEO_FRANCE\", \n                            description= \"query meteo to meteo-france.fr\",\n                            url_adress = \"www.meteo-france.fr/public-db\")\n    remote_controller.add_child(dev2)","key":"AvOXjJpjUD"},{"type":"caption","children":[{"type":"paragraph","children":[{"type":"captionNumber","kind":"code","label":"remote-device-declaration-config","identifier":"remote-device-declaration-config","html_id":"remote-device-declaration-config","enumerator":"8","children":[{"type":"text","value":"Code ","key":"zafY3nY2QK"},{"type":"text","value":"8","key":"e3a8NWlA38"},{"type":"text","value":":","key":"ufZL7fbPLL"}],"template":"Code %s:","key":"URpAWVgiNm"},{"type":"text","value":"Declaration of the remote part of the script driver in config.py of the remote0 controller.","position":{"start":{"line":458,"column":1},"end":{"line":458,"column":1}},"key":"Opjnqh9S1S"}],"key":"kPy3gRTXTO"}],"key":"pND2QoBOc6"}],"enumerator":"8","html_id":"remote-device-declaration-config","key":"vWHVleRIWJ"},{"type":"paragraph","position":{"start":{"line":475,"column":1},"end":{"line":475,"column":1}},"children":[{"type":"text","value":"Now that that devices are created, we need to start the remote controller before starting the client","position":{"start":{"line":475,"column":1},"end":{"line":475,"column":1}},"key":"uoaFAjkLSO"},{"type":"footnoteReference","identifier":"rappel-lancement-remote-server","label":"rappel-lancement-remote-server","position":{"start":{"line":475,"column":1},"end":{"line":475,"column":1}},"number":14,"enumerator":"14","key":"PeRU0YQQaV"},{"type":"text","value":". Once this hardware part is done, we need to do the same on the client side. This is done in the ","position":{"start":{"line":475,"column":1},"end":{"line":475,"column":1}},"key":"kDTTzCm2YA"},{"type":"inlineCode","value":"hardware_setup","position":{"start":{"line":475,"column":1},"end":{"line":475,"column":1}},"key":"VpCSxhMbFO"},{"type":"text","value":" function of the ","position":{"start":{"line":475,"column":1},"end":{"line":475,"column":1}},"key":"ECfMVqu4jm"},{"type":"inlineCode","value":"qc3scripts/config/hardware.py","position":{"start":{"line":475,"column":1},"end":{"line":475,"column":1}},"key":"pdJSWfNoq3"},{"type":"text","value":" file. In our case, we just need to :","position":{"start":{"line":475,"column":1},"end":{"line":475,"column":1}},"key":"DVE5Z8bNtX"}],"key":"TgguYEcrou"},{"type":"list","ordered":false,"spread":false,"position":{"start":{"line":476,"column":1},"end":{"line":478,"column":1}},"children":[{"type":"listItem","spread":true,"position":{"start":{"line":476,"column":1},"end":{"line":476,"column":1}},"children":[{"type":"text","value":"instantiate the timing controller corresponding to remote0 and add it as a child of the timing system,","position":{"start":{"line":476,"column":1},"end":{"line":476,"column":1}},"key":"K9PSAuHWW2"}],"key":"sn5xOz9V10"},{"type":"listItem","spread":true,"position":{"start":{"line":477,"column":1},"end":{"line":478,"column":1}},"children":[{"type":"text","value":"instantiate all software drivers with the same name defined in the remote configuration file and add them as the child of the timing controller","position":{"start":{"line":477,"column":1},"end":{"line":477,"column":1}},"key":"HS2PJu17nT"}],"key":"O3i1n5lIwN"}],"key":"E6H3u8LCPi"},{"type":"container","kind":"code","label":"remote-device-declaration-hardware","identifier":"remote-device-declaration-hardware","children":[{"type":"code","lang":"python","filename":"harware.py","value":"from qcontrol3.driver.misc.meteo_driver import MeteoDevice\n           (....)\ndef hardware_setup(tsys):\n           (....)\n    rem0 = RemoteSoftwareTimingController(\"REMOTE0\")\n    tsys.add_child(rem0)\n    dev = MeteoDevice(\"METEO_CIEL\")\n    rem0.add_child(dev)\n    dev = MeteoDevice(\"METEO_FRANCE\")\n    rem0.add_child(dev)","key":"XYHZXCrlur"},{"type":"caption","children":[{"type":"paragraph","children":[{"type":"captionNumber","kind":"code","label":"remote-device-declaration-hardware","identifier":"remote-device-declaration-hardware","html_id":"remote-device-declaration-hardware","enumerator":"9","children":[{"type":"text","value":"Code ","key":"sHfOw509bP"},{"type":"text","value":"9","key":"XM4ETys47A"},{"type":"text","value":":","key":"zytV87TRh5"}],"template":"Code %s:","key":"NaIKGa0Vun"},{"type":"text","value":"Completion of ","position":{"start":{"line":481,"column":1},"end":{"line":481,"column":1}},"key":"FJLaCqdxGc"},{"type":"inlineCode","value":"harware_setup","position":{"start":{"line":481,"column":1},"end":{"line":481,"column":1}},"key":"VyBjadcZ8q"},{"type":"text","value":" function of ","position":{"start":{"line":481,"column":1},"end":{"line":481,"column":1}},"key":"iAbkHGkLLb"},{"type":"crossReference","position":{"start":{"line":481,"column":1},"end":{"line":481,"column":1}},"children":[{"type":"text","value":"Program ","key":"PeHTODtC5Y"},{"type":"text","value":"2","key":"HHHntlYIaj"}],"identifier":"config-hardware_minimal_example","label":"config-hardware_minimal_example","kind":"code","template":"Program %s","enumerator":"2","resolved":true,"html_id":"config-hardware-minimal-example","key":"ZsDgWIikhL"},{"type":"text","value":". Declaration of the devices should align with the declaration done in the remote configuration file, i.e. names must match.","position":{"start":{"line":481,"column":1},"end":{"line":481,"column":1}},"key":"pqu837oLbp"}],"key":"t6WJfJ4zyy"}],"key":"KpT2Xxo2lp"}],"enumerator":"9","html_id":"remote-device-declaration-hardware","key":"H7AMtr9be9"},{"type":"paragraph","position":{"start":{"line":494,"column":1},"end":{"line":495,"column":1}},"children":[{"type":"text","value":"Now that this is done, one can create user channels associated to those timing channels in the ","position":{"start":{"line":494,"column":1},"end":{"line":494,"column":1}},"key":"Szd0ZN7V3L"},{"type":"inlineCode","value":"channels.py","position":{"start":{"line":494,"column":1},"end":{"line":494,"column":1}},"key":"XWe54PV0fS"},{"type":"text","value":" file. The full name of a timing channel consists of all the nodes that compose it, extending from the trunk to the leaves and separated by dots.\nFor example, to create a user channel associated to the trigger timing channel of the device that query the meteo from ","position":{"start":{"line":494,"column":1},"end":{"line":494,"column":1}},"key":"kKGBcS7m40"},{"type":"link","url":"http://meteo-france.fr","position":{"start":{"line":494,"column":1},"end":{"line":494,"column":1}},"children":[{"type":"text","value":"meteo-france.fr","position":{"start":{"line":494,"column":1},"end":{"line":494,"column":1}},"key":"jONccENHl0"}],"urlSource":"http://meteo-france.fr","key":"acVhjEfRCG"},{"type":"text","value":", one must use the following syntax, in ","position":{"start":{"line":494,"column":1},"end":{"line":494,"column":1}},"key":"TZDqYVCpV2"},{"type":"inlineCode","value":"channels.py","position":{"start":{"line":494,"column":1},"end":{"line":494,"column":1}},"key":"AShn8RT6JV"},{"type":"text","value":":","position":{"start":{"line":494,"column":1},"end":{"line":494,"column":1}},"key":"Kk070sW1jr"}],"key":"iZdq3sSpEj"},{"type":"code","lang":"python","value":"tch = tsys.get_node(\"REMOTE0.METEO_FRANCE.TRIGGER\")\ntch.create_user_channel(\"METEO_FRANCE_TRIG\", \"\", default_value = False)","key":"qXge7BVXKi"},{"type":"paragraph","position":{"start":{"line":500,"column":1},"end":{"line":500,"column":1}},"children":[{"type":"text","value":"Even though it is recommended to create user-friendly devices name, we can now use our device to get the meteo just by adding to our script ","position":{"start":{"line":500,"column":1},"end":{"line":500,"column":1}},"key":"N8xFvqja1A"},{"type":"crossReference","position":{"start":{"line":500,"column":1},"end":{"line":500,"column":1}},"children":[{"type":"text","value":"Program ","key":"IFVaunxHFd"},{"type":"text","value":"4","key":"NVFL3URWKn"}],"identifier":"qc3script-basic","label":"qc3script-basic","kind":"code","template":"Program %s","enumerator":"4","resolved":true,"html_id":"qc3script-basic","key":"GJZ1HiFTfC"},{"type":"text","value":" the following lines.","position":{"start":{"line":500,"column":1},"end":{"line":500,"column":1}},"key":"GtTvVqdSUU"}],"key":"qfg5U4xwWH"},{"type":"code","lang":"python","value":"time = 300 * u.ms\nMETEO_FRANCE_LOC.add(time, \"Brest\")\nMETEO_FRANCE_TRIG.add(time + 30 * u.ms, True)\nMETEO_FRANCE_TRIG.add(time + 80 * u.ms, False)","key":"wty7QWOtGM"},{"type":"paragraph","position":{"start":{"line":508,"column":1},"end":{"line":508,"column":1}},"children":[{"type":"text","value":"If you look into the remote0 shell, you will see that during the cycle, and at the ","position":{"start":{"line":508,"column":1},"end":{"line":508,"column":1}},"key":"vuKCT3QjTx"},{"type":"emphasis","position":{"start":{"line":508,"column":1},"end":{"line":508,"column":1}},"children":[{"type":"text","value":"exact","position":{"start":{"line":508,"column":1},"end":{"line":508,"column":1}},"key":"qhoqOCsC1r"}],"key":"EtBF0QSi2g"},{"type":"text","value":" moment (up to a few milliseconds), the temperature is printed. Well done !","position":{"start":{"line":508,"column":1},"end":{"line":508,"column":1}},"key":"ZBjEFAyILY"}],"key":"HzXcxHOj2d"},{"type":"paragraph","position":{"start":{"line":510,"column":1},"end":{"line":510,"column":1}},"children":[{"type":"text","value":"Note that our device do not save the meteo inside the hdf5 file in our case. If this is needed, for a camera driver for example, the driver can inherit from the WriterDevice class. This class inherits from the SoftwareDevice class but has already two timing channels defined of type boolean (","position":{"start":{"line":510,"column":1},"end":{"line":510,"column":1}},"key":"DHfwpeyN55"},{"type":"inlineCode","value":"TRIG","position":{"start":{"line":510,"column":1},"end":{"line":510,"column":1}},"key":"wnGGEVnXL9"},{"type":"text","value":") and string (","position":{"start":{"line":510,"column":1},"end":{"line":510,"column":1}},"key":"r3wfg57OZj"},{"type":"inlineCode","value":"HDF_PATH","position":{"start":{"line":510,"column":1},"end":{"line":510,"column":1}},"key":"OuoIAkadOy"},{"type":"text","value":"). When the first one is set to ","position":{"start":{"line":510,"column":1},"end":{"line":510,"column":1}},"key":"EWHo73S0yh"},{"type":"emphasis","position":{"start":{"line":510,"column":1},"end":{"line":510,"column":1}},"children":[{"type":"text","value":"True","position":{"start":{"line":510,"column":1},"end":{"line":510,"column":1}},"key":"oiKjzvcCV3"}],"key":"XbKurbUqo5"},{"type":"text","value":", the driver called the ","position":{"start":{"line":510,"column":1},"end":{"line":510,"column":1}},"key":"IxJxVUcOUH"},{"type":"inlineCode","value":"initialize_capture","position":{"start":{"line":510,"column":1},"end":{"line":510,"column":1}},"key":"LdIr8OPr4u"},{"type":"text","value":" method and when set to False it ends the capture by calling the ","position":{"start":{"line":510,"column":1},"end":{"line":510,"column":1}},"key":"f6B3UMEYAC"},{"type":"inlineCode","value":"end_capture","position":{"start":{"line":510,"column":1},"end":{"line":510,"column":1}},"key":"X7evvd4S7A"},{"type":"text","value":" method, and saves the acquired data into the HDF5 file, whose path is given by the string channel, after calling the ","position":{"start":{"line":510,"column":1},"end":{"line":510,"column":1}},"key":"D3gkc1SVIp"},{"type":"inlineCode","value":"process_data","position":{"start":{"line":510,"column":1},"end":{"line":510,"column":1}},"key":"C8Ybkp2s8W"},{"type":"text","value":" method.","position":{"start":{"line":510,"column":1},"end":{"line":510,"column":1}},"key":"aluohcHwY9"}],"key":"Qn3w68K7iK"},{"type":"admonition","kind":"tip","children":[{"type":"admonitionTitle","children":[{"type":"emphasis","position":{"start":{"line":512,"column":1},"end":{"line":512,"column":1}},"children":[{"type":"text","value":"Summary","position":{"start":{"line":512,"column":1},"end":{"line":512,"column":1}},"key":"Olhw0vFtpQ"}],"key":"FKKWoVgYyN"}],"key":"PpaTLHbwU1"},{"type":"paragraph","position":{"start":{"line":513,"column":1},"end":{"line":513,"column":1}},"children":[{"type":"text","value":"In summary, in this section, we learned how to create a driver from scratch. Once the code is set up, the driver must be installed in your environment and declared both in the remote part (","position":{"start":{"line":513,"column":1},"end":{"line":513,"column":1}},"key":"y76jMQHnOi"},{"type":"inlineCode","value":"config.py","position":{"start":{"line":513,"column":1},"end":{"line":513,"column":1}},"key":"JobF7ur6Dg"},{"type":"text","value":") and the server part (","position":{"start":{"line":513,"column":1},"end":{"line":513,"column":1}},"key":"cEhXlKoKje"},{"type":"inlineCode","value":"hardware.py","position":{"start":{"line":513,"column":1},"end":{"line":513,"column":1}},"key":"gz0nn1Um10"},{"type":"text","value":"). Once device is instantiated and added as a grand-child of the timing system, it is possible to create user-channels associated to those channels (","position":{"start":{"line":513,"column":1},"end":{"line":513,"column":1}},"key":"BfK8ZDveiT"},{"type":"inlineCode","value":"channels.py","position":{"start":{"line":513,"column":1},"end":{"line":513,"column":1}},"key":"Fn8ySfOcwW"},{"type":"text","value":"). User channels can then be wrapped into more complex object or just used with the ","position":{"start":{"line":513,"column":1},"end":{"line":513,"column":1}},"key":"lpE3bnXwgl"},{"type":"emphasis","position":{"start":{"line":513,"column":1},"end":{"line":513,"column":1}},"children":[{"type":"text","value":"add","position":{"start":{"line":513,"column":1},"end":{"line":513,"column":1}},"key":"P81wSKXozM"}],"key":"bVRoikkdmv"},{"type":"text","value":" method in the script.","position":{"start":{"line":513,"column":1},"end":{"line":513,"column":1}},"key":"dbxDaPLZ00"}],"key":"Gh6PESjxeB"}],"key":"G6VTUFkKx7"},{"type":"heading","depth":2,"position":{"start":{"line":517,"column":1},"end":{"line":517,"column":1}},"children":[{"type":"text","value":"Our current configuration","position":{"start":{"line":517,"column":1},"end":{"line":517,"column":1}},"key":"RY0pJypM0R"}],"identifier":"our-current-config","label":"our-current-config","html_id":"our-current-config","enumerator":"4","key":"T51KHu01me"},{"type":"paragraph","position":{"start":{"line":519,"column":1},"end":{"line":519,"column":1}},"children":[{"type":"text","value":"I will now give a brief overview of how we structure our code and way of coding sequences. We discovered QControl3 and started to understand its logic while we had other experimental issues, so we had to balance proper coding and quick - and dirty - implementation in order to progress on the experiment. As we had no clear tutorial, it took time to clearly understand the logic behind QControl and, as Python beginners, we had tried our best to do it as clean as possible. Writing this thesis appendix made me realized however that our way to code sequences was in fact quite proper and logical. Last but not least, I think that what belongs to Caesar must be returned to Caesar : even though it is not clearly valued in his PhD thesis, Quentin ","position":{"start":{"line":519,"column":1},"end":{"line":519,"column":1}},"key":"bIPSekiKJo"},{"type":"cite","identifier":"marolleau_quantum_2022","label":"marolleau_quantum_2022","kind":"narrative","position":{"start":{"line":519,"column":747},"end":{"line":519,"column":770}},"children":[{"type":"text","value":"Marolleau (2022)","key":"htkbMbobzL"}],"enumerator":"6","key":"z03r19hMP0"},{"type":"text","value":" made a major contribution to our script structure during summer 2021. His work pioneered the current code structure.","position":{"start":{"line":519,"column":1},"end":{"line":519,"column":1}},"key":"gRpSvFol51"}],"key":"av4D2qQhoF"},{"type":"paragraph","position":{"start":{"line":521,"column":1},"end":{"line":521,"column":1}},"children":[{"type":"text","value":"For future developers, note the code has (slightly) diverged in two (reversible) aspects from the ","position":{"start":{"line":521,"column":1},"end":{"line":521,"column":1}},"key":"fTaLrJZomW"},{"type":"emphasis","position":{"start":{"line":521,"column":1},"end":{"line":521,"column":1}},"children":[{"type":"text","value":"official","position":{"start":{"line":521,"column":1},"end":{"line":521,"column":1}},"key":"stn7uhumc8"}],"key":"ysQDFXSPD4"},{"type":"text","value":" QControl3 version.","position":{"start":{"line":521,"column":1},"end":{"line":521,"column":1}},"key":"IBhOmY2wBd"}],"key":"kQtS3KDlrE"},{"type":"list","ordered":true,"start":1,"spread":false,"position":{"start":{"line":522,"column":1},"end":{"line":525,"column":1}},"children":[{"type":"listItem","spread":true,"position":{"start":{"line":522,"column":1},"end":{"line":522,"column":1}},"children":[{"type":"text","value":"Experimental parameters are not hardcoded in the scripts but are stored in a parameter file that is read during each script execution, i.e., for each run. This choice is motivated in the ","position":{"start":{"line":522,"column":1},"end":{"line":522,"column":1}},"key":"pkTn1KQBxc"},{"type":"crossReference","position":{"start":{"line":522,"column":1},"end":{"line":522,"column":1}},"children":[{"type":"text","value":"first following subsection","position":{"start":{"line":522,"column":1},"end":{"line":522,"column":1}},"key":"WRyuHKkDqi"}],"identifier":"parameter_subsection","label":"parameter_subsection","kind":"heading","template":"{name}","resolved":true,"html_id":"parameter-subsection","key":"ZJwZfmq2dW"},{"type":"text","value":". The consequence is that the ","position":{"start":{"line":522,"column":1},"end":{"line":522,"column":1}},"key":"dmNuMfPrNv"},{"type":"inlineCode","value":"iter_values","position":{"start":{"line":522,"column":1},"end":{"line":522,"column":1}},"key":"c2p4ETI13D"},{"type":"text","value":" are dictionaries which raises an type error when the program tries to save it in the HDF archive.","position":{"start":{"line":522,"column":1},"end":{"line":522,"column":1}},"key":"nJUWJBqD8B"}],"key":"mEuzk6UeDa"},{"type":"listItem","spread":true,"position":{"start":{"line":523,"column":1},"end":{"line":525,"column":1}},"children":[{"type":"text","value":"We do not save data with the HDF format as motivated in the see ","position":{"start":{"line":523,"column":1},"end":{"line":523,"column":1}},"key":"ifG1DhWPhk"},{"type":"crossReference","position":{"start":{"line":523,"column":1},"end":{"line":523,"column":1}},"children":[{"type":"text","value":"the second subsection","position":{"start":{"line":523,"column":1},"end":{"line":523,"column":1}},"key":"FrcKEQybgd"}],"identifier":"save_datas","label":"save_datas","kind":"heading","template":"{name}","resolved":true,"html_id":"save-datas","key":"nx6ywwhG1U"},{"type":"text","value":" and we must therefore assign a custom identifier per shot, as explained in the ","position":{"start":{"line":523,"column":1},"end":{"line":523,"column":1}},"key":"gGBn7bst3Y"},{"type":"crossReference","position":{"start":{"line":523,"column":1},"end":{"line":523,"column":1}},"children":[{"type":"text","value":"third subsection","position":{"start":{"line":523,"column":1},"end":{"line":523,"column":1}},"key":"LpLF85Zbjv"}],"identifier":"he_script","label":"he_script","kind":"heading","template":"{name}","resolved":true,"html_id":"he-script","key":"gsJjipwCd2"},{"type":"text","value":". The consequence of this choice is that we changed a few lines in the ","position":{"start":{"line":523,"column":1},"end":{"line":523,"column":1}},"key":"iYsmfHs84U"},{"type":"inlineCode","value":"qcontrol3_base","position":{"start":{"line":523,"column":1},"end":{"line":523,"column":1}},"key":"GAxDRQORPY"},{"type":"text","value":" code in order to store the experimental configuration. More details are given below.","position":{"start":{"line":523,"column":1},"end":{"line":523,"column":1}},"key":"eSpcjy0i0h"}],"key":"nI6jGQl4je"}],"key":"yj9Zh6c1gv"},{"type":"heading","depth":3,"position":{"start":{"line":527,"column":1},"end":{"line":527,"column":1}},"children":[{"type":"text","value":"Defining a parameter value and scanning a parameter","position":{"start":{"line":527,"column":1},"end":{"line":527,"column":1}},"key":"RnJ9KOXEQN"}],"identifier":"parameter_subsection","label":"parameter_subsection","html_id":"parameter-subsection","key":"OAYlr2woYC"},{"type":"paragraph","position":{"start":{"line":528,"column":1},"end":{"line":528,"column":1}},"children":[{"type":"text","value":"All values used in our code are not hard-coded but defined in a so-called sequence_parameters dictionary. This dictionary is loaded from a json file of the same name. This format was chosen for its nice readability properties - even thought we do not read it any more. At the first iteration of the script, this file content is saved in a hidden file (","position":{"start":{"line":528,"column":1},"end":{"line":528,"column":1}},"key":"bX4SSiQLIK"},{"type":"inlineCode","value":".sequence_parameters.json","position":{"start":{"line":528,"column":1},"end":{"line":528,"column":1}},"key":"XcyuKorxVs"},{"type":"text","value":") so that the user cannot modify any parameter during a sequence. The content of the file is then   loaded into  a dictionary, and interpreted in terms of dimensioned quantities","position":{"start":{"line":528,"column":1},"end":{"line":528,"column":1}},"key":"Yns58y6VrA"},{"type":"footnoteReference","identifier":"sequence_parameter_loading","label":"sequence_parameter_loading","position":{"start":{"line":528,"column":1},"end":{"line":528,"column":1}},"number":15,"enumerator":"15","key":"os6EWiIJbz"},{"type":"text","value":".","position":{"start":{"line":528,"column":1},"end":{"line":528,"column":1}},"key":"jDe7mdU3Rc"}],"key":"RMfBSiqce0"},{"type":"paragraph","position":{"start":{"line":530,"column":1},"end":{"line":530,"column":1}},"children":[{"type":"text","value":"The ","position":{"start":{"line":530,"column":1},"end":{"line":530,"column":1}},"key":"siT5x8y8se"},{"type":"strong","position":{"start":{"line":530,"column":1},"end":{"line":530,"column":1}},"children":[{"type":"text","value":"iter_list","position":{"start":{"line":530,"column":1},"end":{"line":530,"column":1}},"key":"i182omEEvb"}],"key":"lXxFD9GFLH"},{"type":"text","value":" is supposed to be the list containing the scanned parameter values. As we understood QControl logic, if a user wants to scan the ","key":"b5aX7BBkp0"},{"type":"abbreviation","title":"Magneto-Optical Trap","children":[{"type":"text","value":"MOT","key":"tE8mJigMWd"}],"key":"vWb9sKOYOw"},{"type":"text","value":" ","key":"sa01kS8Knv"},{"type":"abbreviation","title":"Acousto-Optics Modulator","children":[{"type":"text","value":"AOM","key":"O6CLvYwIgQ"}],"key":"QBZXiDZbbi"},{"type":"text","value":" frequency, he would hard-write the frequency defined in the script by the ","key":"eyJM4du1iI"},{"type":"inlineCode","value":"iter_value","position":{"start":{"line":530,"column":1},"end":{"line":530,"column":1}},"key":"z3AgqNKCuB"},{"type":"text","value":" so that this value is updated at each run. In our case, every parameter being encoded in the parameters dictionary, we need to update this dictionary at each run. An element of the iter_list is therefore a dictionary whose  entries are keys of the parameters dictionary, for example, ","position":{"start":{"line":530,"column":1},"end":{"line":530,"column":1}},"key":"cWxYDSrCMr"},{"type":"inlineCode","value":"{\"MOT | AOM | freq\" : 80 * u.MHz}","position":{"start":{"line":530,"column":1},"end":{"line":530,"column":1}},"key":"j9FkvjhWEz"},{"type":"text","value":". Since the iter_list elements were not thought to be dictionaries therefore it produce an error when QControl tries to save the iter_value into the HDF5 file. Some remarks about the iter_list definition :","position":{"start":{"line":530,"column":1},"end":{"line":530,"column":1}},"key":"dHjey8MXgF"}],"key":"nkEfzwwf8o"},{"type":"list","ordered":false,"spread":false,"position":{"start":{"line":531,"column":1},"end":{"line":533,"column":1}},"children":[{"type":"listItem","spread":true,"position":{"start":{"line":531,"column":1},"end":{"line":531,"column":1}},"children":[{"type":"text","value":"it can contain several entries to perform double scans,","position":{"start":{"line":531,"column":1},"end":{"line":531,"column":1}},"key":"Nux07X2zNb"}],"key":"R3wyCcg3L6"},{"type":"listItem","spread":true,"position":{"start":{"line":532,"column":1},"end":{"line":533,"column":1}},"children":[{"type":"text","value":"it is a global value of ","position":{"start":{"line":532,"column":1},"end":{"line":532,"column":1}},"key":"apfadKl2RI"},{"type":"inlineCode","value":"pys","position":{"start":{"line":532,"column":1},"end":{"line":532,"column":1}},"key":"J5UtWlXWHj"},{"type":"text","value":" files so it is define when the script is uploaded and not at each run. In practice, this means that we define the iter_list at the first execution, ","position":{"start":{"line":532,"column":1},"end":{"line":532,"column":1}},"key":"aRCasiCvDG"},{"type":"emphasis","position":{"start":{"line":532,"column":1},"end":{"line":532,"column":1}},"children":[{"type":"text","value":"e.g.","position":{"start":{"line":532,"column":1},"end":{"line":532,"column":1}},"key":"LcPs2TZhCC"}],"key":"X8DhOOBCIU"},{"type":"text","value":" when iter_step is -1","position":{"start":{"line":532,"column":1},"end":{"line":532,"column":1}},"key":"tt1HJCZ4oY"},{"type":"footnoteReference","identifier":"iter_step_values","label":"iter_step_values","position":{"start":{"line":532,"column":1},"end":{"line":532,"column":1}},"number":16,"enumerator":"16","key":"oE2cdIjRNH"},{"type":"text","value":".","position":{"start":{"line":532,"column":1},"end":{"line":532,"column":1}},"key":"RZQABYvRGL"}],"key":"jo03gy9YSP"}],"key":"J4GK57YF3q"},{"type":"heading","depth":3,"position":{"start":{"line":535,"column":1},"end":{"line":535,"column":1}},"children":[{"type":"text","value":"Saving data","position":{"start":{"line":535,"column":1},"end":{"line":535,"column":1}},"key":"XXZNMWiMxw"}],"identifier":"save_datas","label":"save_datas","html_id":"save-datas","key":"RMXXdB89sm"},{"type":"paragraph","position":{"start":{"line":537,"column":1},"end":{"line":537,"column":1}},"children":[{"type":"text","value":"The data repository has the following form ","position":{"start":{"line":537,"column":1},"end":{"line":537,"column":1}},"key":"dZByQaDpFJ"},{"type":"inlineCode","value":"day / SEQ / STEP","position":{"start":{"line":537,"column":1},"end":{"line":537,"column":1}},"key":"TV3eYJyu60"},{"type":"text","value":" where ","position":{"start":{"line":537,"column":1},"end":{"line":537,"column":1}},"key":"QOuyP4bZmc"},{"type":"inlineCode","value":"SEQ","position":{"start":{"line":537,"column":1},"end":{"line":537,"column":1}},"key":"QH6mMlNZbq"},{"type":"text","value":" is the sequence number, an integer starting each day at and ","position":{"start":{"line":537,"column":1},"end":{"line":537,"column":1}},"key":"dnuxplVGXc"},{"type":"inlineCode","value":"STEP","position":{"start":{"line":537,"column":1},"end":{"line":537,"column":1}},"key":"DImm2BfYUk"},{"type":"text","value":" is the shot iteration number. Even thought QControl3 gives the possibility to save all data associated to a run into a single HDF5 file, we finally decided to abandon this way of saving data. First reason is that opening an HDF5 file to get a few information or just an image is quite long compare to a simple file : one has to open ","position":{"start":{"line":537,"column":1},"end":{"line":537,"column":1}},"key":"DyXjQYAHVA"},{"type":"emphasis","position":{"start":{"line":537,"column":1},"end":{"line":537,"column":1}},"children":[{"type":"text","value":"all","position":{"start":{"line":537,"column":1},"end":{"line":537,"column":1}},"key":"JqcWFnLtSb"}],"key":"zBUohIL9KQ"},{"type":"text","value":" data and not only the one you are interested in. Loading data to briefly analyze a sequence was a pain when the number of runs was above 100","position":{"start":{"line":537,"column":1},"end":{"line":537,"column":1}},"key":"OeguqSIq9E"},{"type":"footnoteReference","identifier":"11","label":"11","position":{"start":{"line":537,"column":1},"end":{"line":537,"column":1}},"number":11,"enumerator":"11","key":"KM4lKaNhB8"},{"type":"text","value":". An other reason is that variables and scripts are not easily accessible in HDF5 file which is not convenient when one needs only to check an old sequence. Because of this choice, we always run iterations, and never loop nor single runs, because we need the iter_step to increase at each cycle so that we know at which iteration in the sequence we are.","position":{"start":{"line":537,"column":1},"end":{"line":537,"column":1}},"key":"ePJiqoGyib"}],"key":"FnfZimy2aI"},{"type":"paragraph","position":{"start":{"line":541,"column":1},"end":{"line":541,"column":1}},"children":[{"type":"text","value":"QControl allows the user the option to save or not save its data. In addition to the HDF file containing the data, QControl also generates an HDF5 archive with the experimental configuration. A graphical user interface (GUI) called ","position":{"start":{"line":541,"column":1},"end":{"line":541,"column":1}},"key":"RgmOtkGmTn"},{"type":"link","url":"https://gitlab.in2p3.fr/gaz-quantiques-lcf/helium-1/qcontrol3_gui_sequenceviewer","position":{"start":{"line":541,"column":1},"end":{"line":541,"column":1}},"children":[{"type":"text","value":"sequence_viewer","position":{"start":{"line":541,"column":1},"end":{"line":541,"column":1}},"key":"K5eLkThdQ1"}],"urlSource":"https://gitlab.in2p3.fr/gaz-quantiques-lcf/helium-1/qcontrol3_gui_sequenceviewer","key":"uqPce8Pc0a"},{"type":"text","value":" was developed in Munich to load this file and display the content of each channel in the sequence. To avoid reprogramming this entirely, we made some modifications to ","position":{"start":{"line":541,"column":1},"end":{"line":541,"column":1}},"key":"Ni5IdVYufw"},{"type":"inlineCode","value":"qcontrol3-base","position":{"start":{"line":541,"column":1},"end":{"line":541,"column":1}},"key":"vWcuX3Ci9U"},{"type":"text","value":" to save only this experimental configuration file. It is worth noting that updating the Python version or the qcontrol3-base from the ","key":"c1eeieXyGS"},{"type":"abbreviation","title":"Max Planck Institute of Quantum Optics","children":[{"type":"text","value":"MPQ","key":"d6K3xO6K8q"}],"key":"LqAh1BwxC9"},{"type":"text","value":" may necessitate an update to this modification.","key":"uum977nspd"}],"key":"gA2C0LUzYV"},{"type":"heading","depth":3,"position":{"start":{"line":544,"column":1},"end":{"line":544,"column":1}},"children":[{"type":"text","value":"The HeliumScript class and spirit of the code","position":{"start":{"line":544,"column":1},"end":{"line":544,"column":1}},"key":"Tvtg9v4uQG"}],"identifier":"he_script","label":"he_script","html_id":"he-script","key":"MCToTJVfvU"},{"type":"paragraph","position":{"start":{"line":545,"column":1},"end":{"line":545,"column":1}},"children":[{"type":"text","value":"Any script we use in the lab inherits from the HeliumScript class, which contains methods and attributes common to any script. This class sets the sequence number, the cycle number, the sequence directory, loads the ","position":{"start":{"line":545,"column":1},"end":{"line":545,"column":1}},"key":"BlOvyH4eEj"},{"type":"inlineCode","value":"sequence_parameters","position":{"start":{"line":545,"column":1},"end":{"line":545,"column":1}},"key":"C583KX0ohQ"},{"type":"text","value":" and update it if one scans a parameter. When the user starts a sequence, the following steps are performed by the HeliumScript class.","position":{"start":{"line":545,"column":1},"end":{"line":545,"column":1}},"key":"ku5NhSTlHT"}],"key":"fKdHOCkGHD"},{"type":"list","ordered":false,"spread":false,"position":{"start":{"line":547,"column":1},"end":{"line":554,"column":1}},"children":[{"type":"listItem","spread":true,"position":{"start":{"line":547,"column":1},"end":{"line":547,"column":1}},"children":[{"type":"text","value":"it sets the default path to look for camera picture and configuration files,","position":{"start":{"line":547,"column":1},"end":{"line":547,"column":1}},"key":"AtTCB2XXVw"}],"key":"UEJEuxru7P"},{"type":"listItem","spread":true,"position":{"start":{"line":548,"column":1},"end":{"line":548,"column":1}},"children":[{"type":"text","value":"it sets the cycle id, defined as the absolute time of the current cycle in seconds, relatively to the epoch time for QControl3 (the first qcontrol-Helium-","key":"wMerJ8jJRH"},{"type":"abbreviation","title":"Magneto-Optical Trap","children":[{"type":"text","value":"MOT","key":"SmbJ3wxBWe"}],"key":"PY3p3dqV8H"},{"type":"text","value":" time 1619049600: April, 22nd of 2021 for humans),","key":"ZT5giFhYVZ"}],"key":"o1fdoD7vYM"},{"type":"listItem","spread":true,"position":{"start":{"line":549,"column":1},"end":{"line":549,"column":1}},"children":[{"type":"text","value":"it sets the day directory, defined the sequence number and its associated directory depending on the last folders in the day directory. If the last folder was 014, this means that the sequence is 14 if the iteration step is greater than 1 or it means that one starts a new sequence hence it creates the folder 015 and set the sequence number to 15. Not that this fragile way of saving data implies that one should not modify the day folder on the server when the experiment is running.","position":{"start":{"line":549,"column":1},"end":{"line":549,"column":1}},"key":"RCmyZW4Qwj"}],"key":"YFfnluMeIx"},{"type":"listItem","spread":true,"position":{"start":{"line":550,"column":1},"end":{"line":550,"column":1}},"children":[{"type":"text","value":"it loads the sequence parameters file from the hidden sequence parameters file. If the iteration step is 0, it copies the ","position":{"start":{"line":550,"column":1},"end":{"line":550,"column":1}},"key":"ej9vswLsA3"},{"type":"inlineCode","value":"sequence_parameters.json","position":{"start":{"line":550,"column":1},"end":{"line":550,"column":1}},"key":"yZl6y9Y0GD"},{"type":"text","value":" file into the hidden file so that parameters of a sequence cannot be changed while running.","position":{"start":{"line":550,"column":1},"end":{"line":550,"column":1}},"key":"FGnCqKcZUy"}],"key":"uGUvk3IaTB"},{"type":"listItem","spread":true,"position":{"start":{"line":551,"column":1},"end":{"line":551,"column":1}},"children":[{"type":"text","value":"it updates the parameters dictionary with respect to the iteration value of the ","position":{"start":{"line":551,"column":1},"end":{"line":551,"column":1}},"key":"Kkx2dS5wnT"},{"type":"inlineCode","value":"iter_list","position":{"start":{"line":551,"column":1},"end":{"line":551,"column":1}},"key":"B3uuq8vfaI"},{"type":"text","value":".","position":{"start":{"line":551,"column":1},"end":{"line":551,"column":1}},"key":"dnePwIfyKz"}],"key":"t4Vns7vY1I"},{"type":"listItem","spread":true,"position":{"start":{"line":552,"column":1},"end":{"line":552,"column":1}},"children":[{"type":"text","value":"it instantiates script devices i.e. it gives nice name to user_channels.","position":{"start":{"line":552,"column":1},"end":{"line":552,"column":1}},"key":"uQGAOBZHra"}],"key":"BRWjdhQwfF"},{"type":"listItem","spread":true,"position":{"start":{"line":553,"column":1},"end":{"line":554,"column":1}},"children":[{"type":"text","value":"it instantiates subscripts class like Raman or c","key":"rMZFj9Qwan"},{"type":"abbreviation","title":"Magneto-Optical Trap","children":[{"type":"text","value":"MOT","key":"k9eZfcManM"}],"key":"p2i2ajwgYQ"},{"type":"text","value":" for example. Note that as shown in ","key":"paKPcqdpeY"},{"type":"crossReference","position":{"start":{"line":553,"column":1},"end":{"line":553,"column":1}},"children":[{"type":"text","value":"Figure ","key":"DAgbDMxf19"},{"type":"text","value":"4","key":"gGSN9MSmtW"}],"identifier":"helium-script-uml","label":"helium-script-UML","kind":"figure","template":"Figure %s","enumerator":"4","resolved":true,"html_id":"helium-script-uml","key":"TRhsrLzEoZ"},{"type":"text","value":", subscripts are instantiated with the sequence parameters and they also instantiates script devices (as they inherits from the ScriptObject class)","position":{"start":{"line":553,"column":1},"end":{"line":553,"column":1}},"key":"yXT9FWqleN"}],"key":"b3zpPBU6xD"}],"key":"FMzlWGOw29"},{"type":"paragraph","position":{"start":{"line":555,"column":1},"end":{"line":555,"column":1}},"children":[{"type":"text","value":"Note that the helium script also defines methods to save data that should be called at the end of any script to save the content of the script folder.","position":{"start":{"line":555,"column":1},"end":{"line":555,"column":1}},"key":"UtxH8EMUSh"}],"key":"tilsOZrKr1"},{"type":"container","kind":"figure","identifier":"helium-script-uml","label":"helium-script-UML","children":[{"type":"image","url":"/~gondret/phd_manuscript/build/uml_diagram_qc3scrip-1867614d79548e3277cb98a575d0e895.png","alt":"Helium Script Scheme","width":"100%","align":"center","key":"caEhtD7Nkh","urlSource":"images/uml_diagram_qc3scripts.png","urlOptimized":"/~gondret/phd_manuscript/build/uml_diagram_qc3scrip-1867614d79548e3277cb98a575d0e895.webp"},{"type":"caption","children":[{"type":"paragraph","position":{"start":{"line":563,"column":1},"end":{"line":563,"column":1}},"children":[{"type":"captionNumber","kind":"figure","label":"helium-script-UML","identifier":"helium-script-uml","html_id":"helium-script-uml","enumerator":"4","children":[{"type":"text","value":"Figure ","key":"YErh7uWiUM"},{"type":"text","value":"4","key":"ZFahr33ps9"},{"type":"text","value":":","key":"NJsWaJLB5G"}],"template":"Figure %s:","key":"z9ZSu9TYTL"},{"type":"text","value":"UML diagram of our scripts. Inheritance is represented by an arrow toward the mother class and aggregation with a diamond near the aggregate. Any script (","key":"g3Gtwg1kmj"},{"type":"abbreviation","title":"Magneto-Optical Trap","children":[{"type":"text","value":"MOT","key":"UlzHMR1izN"}],"key":"hl8ZsRVC9e"},{"type":"text","value":", MT, ","key":"F9UbDXTqsp"},{"type":"abbreviation","title":"Optical Dipole Trap","children":[{"type":"text","value":"ODT","key":"c1WvfD79oZ"}],"key":"GFeybfNLpw"},{"type":"text","value":")  must have a ","key":"xoZ6j47VdZ"},{"type":"inlineCode","value":"main","position":{"start":{"line":563,"column":1},"end":{"line":563,"column":1}},"key":"L3n9Gtj9oi"},{"type":"text","value":" method to be run that contain the list of event of the sequence and inherits from the HeliumScript class, our base mother class. When instantiated, the HeliumScript gathers the sequence parameters from a configuration file and interprets its entries as qunits quantities. It then instantiate all device (red) from the experiment : channels of the sequencer as well as string channels to dialog with different instruments. A device can be a simple ","position":{"start":{"line":563,"column":1},"end":{"line":563,"column":1}},"key":"g7qdw2vVce"},{"type":"inlineCode","value":"DigitalObject","position":{"start":{"line":563,"column":1},"end":{"line":563,"column":1}},"key":"r3XHZpjjoz"},{"type":"text","value":" (a switch for example) or a more complex object composed of several other channels (a VCO for example is composed of two ","position":{"start":{"line":563,"column":1},"end":{"line":563,"column":1}},"key":"acQ0VDUgvv"},{"type":"inlineCode","value":"AnalogObject","position":{"start":{"line":563,"column":1},"end":{"line":563,"column":1}},"key":"er2UXkSiYC"},{"type":"text","value":" and one ","position":{"start":{"line":563,"column":1},"end":{"line":563,"column":1}},"key":"AnLFZ9fV2g"},{"type":"inlineCode","value":"DigitalObject","position":{"start":{"line":563,"column":1},"end":{"line":563,"column":1}},"key":"fDX0HoAGVA"},{"type":"text","value":"). The class instantiates also each subscripts, passing it the parameter dictionary and the devices instantiated. The various method defined in each subscript are then called by the daughter class.","position":{"start":{"line":563,"column":1},"end":{"line":563,"column":1}},"key":"usMMCceQYV"}],"key":"BWnkIThRAo"}],"key":"BQF2ZY5xDb"}],"enumerator":"4","html_id":"helium-script-uml","key":"frijur9PmA"},{"type":"heading","depth":3,"position":{"start":{"line":565,"column":1},"end":{"line":565,"column":1}},"children":[{"type":"text","value":"Remotes currently implemented","position":{"start":{"line":565,"column":1},"end":{"line":565,"column":1}},"key":"abauxAI6Wb"}],"identifier":"remotes-currently-implemented","label":"Remotes currently implemented","html_id":"remotes-currently-implemented","implicit":true,"key":"Srj5Kx3AER"},{"type":"paragraph","position":{"start":{"line":567,"column":1},"end":{"line":567,"column":1}},"children":[{"type":"text","value":"As with any other cold atom experiment, we use many other devices that are programmed and triggered during a sequence. Each device requires a specific driver:","position":{"start":{"line":567,"column":1},"end":{"line":567,"column":1}},"key":"Eo6pQvEJR7"}],"key":"BN8oetXKrT"},{"type":"list","ordered":false,"spread":false,"position":{"start":{"line":568,"column":1},"end":{"line":576,"column":1}},"children":[{"type":"listItem","spread":true,"position":{"start":{"line":568,"column":1},"end":{"line":568,"column":1}},"children":[{"type":"strong","position":{"start":{"line":568,"column":1},"end":{"line":568,"column":1}},"children":[{"type":"text","value":"SCPI","position":{"start":{"line":568,"column":1},"end":{"line":568,"column":1}},"key":"d2rkWJBSby"}],"key":"OE6EewVZso"},{"type":"text","value":": Many manufactured devices use the SCPI convention to send commands. Such devices were already programmed. This is how we program the Rigol DG4202 (for radio-frequency evaporation and the 1064 nm pair lattice power ramp), the Anapico (radio-frequency generator for the Raman 2 beam and the 1064 nm lattice), the Keysight 33522B waveform generator (sinc shaping for the Bragg pulses), and the Agilent devices.","position":{"start":{"line":568,"column":1},"end":{"line":568,"column":1}},"key":"ISsfxTHDKX"}],"key":"LzMXqCWvz8"},{"type":"listItem","spread":true,"position":{"start":{"line":569,"column":1},"end":{"line":569,"column":1}},"children":[{"type":"strong","position":{"start":{"line":569,"column":1},"end":{"line":569,"column":1}},"children":[{"type":"text","value":"Socket-type devices","position":{"start":{"line":569,"column":1},"end":{"line":569,"column":1}},"key":"IjBPO03JqI"}],"key":"WZkNVfBryT"},{"type":"text","value":": Some other devices do not work with SCPI commands but with a less evolved protocol scheme called socket. This is the case with the R&S HMP4040 power supply (magnetic bias during the molasses and the dipole trap), and the TTI TGF4242 waveform generator (","key":"P14Lt6226y"},{"type":"abbreviation","title":"Radio-frequency","children":[{"type":"text","value":"RF","key":"X3GJvKXc5l"}],"key":"GF2tNlnD2T"},{"type":"text","value":" frequency sweep for the Bragg pulses).","key":"ZHUpu4vLR2"}],"key":"TTOmcjr6C8"},{"type":"listItem","spread":true,"position":{"start":{"line":570,"column":1},"end":{"line":570,"column":1}},"children":[{"type":"strong","position":{"start":{"line":570,"column":1},"end":{"line":570,"column":1}},"children":[{"type":"text","value":"Camera Xenics","position":{"start":{"line":570,"column":1},"end":{"line":570,"column":1}},"key":"W4WjfhVQIE"}],"key":"bizqjSmB3q"},{"type":"text","value":": We have never been able to remotely control the camera. Since we do not change its properties much (exposure time and so on), we program it on a daily basis to save the picture in a folder when the camera is triggered. The driver then accesses this folder and uploads the latest image found to the sequence repository (or the HDF file when it was used).","position":{"start":{"line":570,"column":1},"end":{"line":570,"column":1}},"key":"SYUv34YyQ1"}],"key":"TJPJb3phqr"},{"type":"listItem","spread":true,"position":{"start":{"line":571,"column":1},"end":{"line":571,"column":1}},"children":[{"type":"strong","position":{"start":{"line":571,"column":1},"end":{"line":571,"column":1}},"children":[{"type":"text","value":"The ","key":"adl3Tmwn8D"},{"type":"abbreviation","title":"Micro-Channel Plate","children":[{"type":"text","value":"MCP","key":"yxaHxnpyjN"}],"key":"Ioy6UOQYyN"},{"type":"text","value":" driver","key":"pP4kQeW98L"}],"key":"CAJGDrNwoF"},{"type":"text","value":" simply writes in a file where the ","key":"ADVJXGmbUw"},{"type":"abbreviation","title":"Time-to-Digital Converter","children":[{"type":"text","value":"TDC","key":"MJ9sjDHidP"}],"key":"RrdFQTmrJs"},{"type":"text","value":" driver should save the data (it saves the ‘cycle_prefix’). Indeed, the ","key":"iKtt35pWK8"},{"type":"abbreviation","title":"Time-to-Digital Converter","children":[{"type":"text","value":"TDC","key":"XtEiNeu13v"}],"key":"JlJVHWOK8Y"},{"type":"text","value":" acquisition window is set by a digital trigger. The recorded data are then sent to a Windows computer for Windows driver reasons, on which the reconstruction program runs continuously. Each time the program receives data from the ","key":"QC3IeJS7Pv"},{"type":"abbreviation","title":"Time-to-Digital Converter","children":[{"type":"text","value":"TDC","key":"ysST6zCVc1"}],"key":"tPzRpu3RFC"},{"type":"text","value":", it reads a file in which the cycle prefix is written.","key":"As4npZYKkP"}],"key":"puXzj2Iox7"},{"type":"listItem","spread":true,"position":{"start":{"line":572,"column":1},"end":{"line":576,"column":1}},"children":[{"type":"strong","position":{"start":{"line":572,"column":1},"end":{"line":572,"column":1}},"children":[{"type":"text","value":"Picoscope drivers","position":{"start":{"line":572,"column":1},"end":{"line":572,"column":1}},"key":"RcBNo677c8"}],"key":"pTuzGunNm4"},{"type":"text","value":": PicoTech develops PC oscilloscopes that can be remotely controlled. In order to save experimental signals, we have developed three drivers:","position":{"start":{"line":572,"column":1},"end":{"line":572,"column":1}},"key":"RmwI0ex3HE"},{"type":"list","ordered":false,"spread":false,"position":{"start":{"line":573,"column":1},"end":{"line":576,"column":1}},"children":[{"type":"listItem","spread":true,"position":{"start":{"line":573,"column":1},"end":{"line":573,"column":1}},"children":[{"type":"emphasis","position":{"start":{"line":573,"column":1},"end":{"line":573,"column":1}},"children":[{"type":"text","value":"The Picoscope3000","position":{"start":{"line":573,"column":1},"end":{"line":573,"column":1}},"key":"APon4b1QjP"}],"key":"AiKsvGdNjN"},{"type":"text","value":" driver, for a four-channel oscilloscope, is used to monitor and fit the Bragg interferometric sequence. We use it to access the absolute phase of our interferometer.","position":{"start":{"line":573,"column":1},"end":{"line":573,"column":1}},"key":"kQeNqFKd93"}],"key":"yqmCRPdNQJ"},{"type":"listItem","spread":true,"position":{"start":{"line":574,"column":1},"end":{"line":574,"column":1}},"children":[{"type":"emphasis","position":{"start":{"line":574,"column":1},"end":{"line":574,"column":1}},"children":[{"type":"text","value":"The Picoscope2000","position":{"start":{"line":574,"column":1},"end":{"line":574,"column":1}},"key":"oOZ6DkiO9b"}],"key":"chRBq7D12x"},{"type":"text","value":" driver, for the two-channel device, is used to save and fit the arrival time of the ","key":"kO5cRegoLP"},{"type":"abbreviation","title":"Bose-Einstein Condensate","children":[{"type":"text","value":"BEC","key":"uvLiapNvVk"}],"key":"UrcZiCdz6u"},{"type":"text","value":" on the ","key":"AdbrV8M2Vx"},{"type":"abbreviation","title":"Micro-Channel Plate","children":[{"type":"text","value":"MCP","key":"pEtBUiLgif"}],"key":"BmpRlqgY7W"},{"type":"text","value":" and to recenter data.","key":"AkKg290zW8"}],"key":"AwKe9v62q4"},{"type":"listItem","spread":true,"position":{"start":{"line":575,"column":1},"end":{"line":576,"column":1}},"children":[{"type":"emphasis","position":{"start":{"line":575,"column":1},"end":{"line":575,"column":1}},"children":[{"type":"text","value":"The Picolog","position":{"start":{"line":575,"column":1},"end":{"line":575,"column":1}},"key":"qRKAOdnSnO"}],"key":"Ma0JB0yN8E"},{"type":"text","value":" driver registers data with a lower time-base to enhance the possible drifts of beam power (cooling lasers especially, for example the ","key":"s6PPP12qUF"},{"type":"abbreviation","title":"Magneto-Optical Trap","children":[{"type":"text","value":"MOT","key":"oBNZhEgEH4"}],"key":"xcUVkosUhg"},{"type":"text","value":").","key":"VIzzbRHdms"}],"key":"djH95nXTKm"}],"key":"iGbXEHzQ1D"}],"key":"MLVpB8pLv3"}],"key":"Lx5ihf7qJ4"},{"type":"heading","depth":3,"position":{"start":{"line":577,"column":1},"end":{"line":577,"column":1}},"children":[{"type":"text","value":"The scan controller","position":{"start":{"line":577,"column":1},"end":{"line":577,"column":1}},"key":"BbLVjGNMUz"}],"identifier":"the-scan-controller","label":"The scan controller","html_id":"the-scan-controller","implicit":true,"key":"JJaU5COPX8"},{"type":"paragraph","position":{"start":{"line":578,"column":1},"end":{"line":578,"column":1}},"children":[{"type":"text","value":"On a daily basis, we use a ","position":{"start":{"line":578,"column":1},"end":{"line":578,"column":1}},"key":"QJMMAOXFWn"},{"type":"crossReference","position":{"start":{"line":578,"column":1},"end":{"line":578,"column":1}},"children":[{"type":"text","value":"graphical user interface","position":{"start":{"line":578,"column":1},"end":{"line":578,"column":1}},"key":"lGIdHD5oF2"}],"identifier":"scan_controller","label":"scan_controller","kind":"figure","template":"Figure %s","enumerator":"5","resolved":true,"html_id":"scan-controller","key":"FcHYrRoNhJ"},{"type":"text","value":" called ","position":{"start":{"line":578,"column":1},"end":{"line":578,"column":1}},"key":"ScmA1DlYEm"},{"type":"inlineCode","value":"scan-controller","position":{"start":{"line":578,"column":1},"end":{"line":578,"column":1}},"key":"mmPN2nPbHh"},{"type":"text","value":". The idea of this GUI was to be as the more agnostic possible meaning the code can be effortless run without it","position":{"start":{"line":578,"column":1},"end":{"line":578,"column":1}},"key":"P9wqVTQeCM"},{"type":"footnoteReference","identifier":"scan-origin","label":"scan-origin","position":{"start":{"line":578,"column":1},"end":{"line":578,"column":1}},"number":17,"enumerator":"17","key":"qipGCAXbKE"},{"type":"text","value":". When running an experiment, we want to run a sequence providing all experiment parameters, which variable should be changed at each cycle (scanned in our language) and which value to save for the analysis","position":{"start":{"line":578,"column":1},"end":{"line":578,"column":1}},"key":"vvF04GMjPZ"},{"type":"footnoteReference","identifier":"scan_save_values","label":"scan_save_values","position":{"start":{"line":578,"column":1},"end":{"line":578,"column":1}},"number":18,"enumerator":"18","key":"QamrBPncwy"},{"type":"text","value":". Hence, the ScanController just saves three files :","position":{"start":{"line":578,"column":1},"end":{"line":578,"column":1}},"key":"doWOREcjyi"}],"key":"LNGTWEOeRt"},{"type":"list","ordered":false,"spread":false,"position":{"start":{"line":579,"column":1},"end":{"line":582,"column":1}},"children":[{"type":"listItem","spread":true,"position":{"start":{"line":579,"column":1},"end":{"line":579,"column":1}},"children":[{"type":"inlineCode","value":"sequence_parameters.json","position":{"start":{"line":579,"column":1},"end":{"line":579,"column":1}},"key":"XwjXvh1CQM"},{"type":"text","value":" : contains the value of the experiment parameters,","position":{"start":{"line":579,"column":1},"end":{"line":579,"column":1}},"key":"YVVBp9jfIU"}],"key":"JpLhtRV6cA"},{"type":"listItem","spread":true,"position":{"start":{"line":580,"column":1},"end":{"line":580,"column":1}},"children":[{"type":"inlineCode","value":".scan_parameters.json","position":{"start":{"line":580,"column":1},"end":{"line":580,"column":1}},"key":"NFPJ6Oxtvh"},{"type":"text","value":" : contains a dictionnary with the parameters that should be scanned : it contains the ","position":{"start":{"line":580,"column":1},"end":{"line":580,"column":1}},"key":"sKw4G13bZO"},{"type":"emphasis","position":{"start":{"line":580,"column":1},"end":{"line":580,"column":1}},"children":[{"type":"text","value":"key","position":{"start":{"line":580,"column":1},"end":{"line":580,"column":1}},"key":"AgRQXpfS4n"}],"key":"j0rBc8Jml7"},{"type":"text","value":" of the parameter (its unique identifier), its minimum and maximum values as well as the number of values to scan. This file is then red and interpreted by the  ","position":{"start":{"line":580,"column":1},"end":{"line":580,"column":1}},"key":"duxfgYJhsL"},{"type":"inlineCode","value":"scan_from_controller","position":{"start":{"line":580,"column":1},"end":{"line":580,"column":1}},"key":"Pw06ub2yqH"},{"type":"text","value":" and function from qc3scripts. In order to perform more complex scans (i.e. changing twice parameter at the same time), it is possible to redefine within the code the ","position":{"start":{"line":580,"column":1},"end":{"line":580,"column":1}},"key":"ChQUFa2Zbu"},{"type":"inlineCode","value":"iter_list","position":{"start":{"line":580,"column":1},"end":{"line":580,"column":1}},"key":"K99YHEmCVp"},{"type":"text","value":" instead of calling the ","position":{"start":{"line":580,"column":1},"end":{"line":580,"column":1}},"key":"WopB2z5ano"},{"type":"inlineCode","value":"scan_from_controller","position":{"start":{"line":580,"column":1},"end":{"line":580,"column":1}},"key":"LVUX2wsUkt"},{"type":"text","value":" function.","position":{"start":{"line":580,"column":1},"end":{"line":580,"column":1}},"key":"UTITCJLSUZ"}],"key":"XGgkDkofkF"},{"type":"listItem","spread":true,"position":{"start":{"line":581,"column":1},"end":{"line":582,"column":1}},"children":[{"type":"inlineCode","value":".hal_dictionary.json","position":{"start":{"line":581,"column":1},"end":{"line":581,"column":1}},"key":"z2JfOy3k5v"},{"type":"text","value":" : contains a list of the parameters that are registred at the end of the run. Note that the unit complited in the scan controller must match the true unit of the parameter or it will raise an error when QC3 tries to executes the file.","position":{"start":{"line":581,"column":1},"end":{"line":581,"column":1}},"key":"xrtobUNt8d"}],"key":"ts9Ec3jGH9"}],"key":"g9dTJyG1Dc"},{"type":"container","kind":"figure","identifier":"scan_controller","label":"scan_controller","children":[{"type":"image","url":"/~gondret/phd_manuscript/build/gui_scan_controller-1b968ab8ed929d258209b589c6e0f8f4.png","alt":"The Wonderful Scan Controller","width":"100%","align":"center","key":"Q9SlaQNyYf","urlSource":"images/gui_scan_controller.png","urlOptimized":"/~gondret/phd_manuscript/build/gui_scan_controller-1b968ab8ed929d258209b589c6e0f8f4.webp"},{"type":"caption","children":[{"type":"paragraph","position":{"start":{"line":591,"column":1},"end":{"line":591,"column":1}},"children":[{"type":"captionNumber","kind":"figure","label":"scan_controller","identifier":"scan_controller","html_id":"scan-controller","enumerator":"5","children":[{"type":"text","value":"Figure ","key":"CyVSm1CTOl"},{"type":"text","value":"5","key":"qFtss83SBJ"},{"type":"text","value":":","key":"jTLiFyrTfv"}],"template":"Figure %s:","key":"PlnBuneswX"},{"type":"text","value":"The GUI used to monitor the experiment. The user define here the parameter used and if the parameter should be saved in a specific file for immediate analysis. Scanning a parameter is made possible by clicking the ","position":{"start":{"line":591,"column":1},"end":{"line":591,"column":1}},"key":"uD5xm8dGlw"},{"type":"emphasis","position":{"start":{"line":591,"column":1},"end":{"line":591,"column":1}},"children":[{"type":"text","value":"Scan","position":{"start":{"line":591,"column":1},"end":{"line":591,"column":1}},"key":"pN4m1KPg0z"}],"key":"gSawpuQBLo"},{"type":"text","value":" button. Subsequence are separated in different tabs, who’s color change depending if the subsequence is run or not. For developers, the code tried to respect the ","position":{"start":{"line":591,"column":1},"end":{"line":591,"column":1}},"key":"auThxux4b4"},{"type":"link","url":"https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller","position":{"start":{"line":591,"column":1},"end":{"line":591,"column":1}},"children":[{"type":"text","value":"“MVC”","position":{"start":{"line":591,"column":1},"end":{"line":591,"column":1}},"key":"LS7hGJCvcf"}],"urlSource":"https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller","data":{"page":"Model%E2%80%93view%E2%80%93controller","wiki":"https://en.wikipedia.org/","lang":"en"},"internal":false,"protocol":"wiki","key":"VxyaNktNBB"},{"type":"text","value":"  (Model-View-Controller) design pattern.","position":{"start":{"line":591,"column":1},"end":{"line":591,"column":1}},"key":"st9E3u697m"}],"key":"WnyEnDlwjN"}],"key":"EYRGhRWC5W"}],"enumerator":"5","html_id":"scan-controller","key":"TddCcaobWP"},{"type":"comment","value":" \n################################\n    NOTES DE BAS DE PAGE\n################################\n ","key":"eUFjQSNdFy"},{"type":"footnoteDefinition","identifier":"ciceroisa","label":"ciceroisa","position":{"start":{"line":595,"column":1},"end":{"line":595,"column":1}},"children":[{"type":"paragraph","position":{"start":{"line":36,"column":1},"end":{"line":36,"column":1}},"children":[{"type":"text","value":"The year 2021 A.C. The Quantum Gases NI users group is entirely occupied by the Cicero Words Generator. Well not entirely! One small team of Rubidium still holds out against the Cicero dictator and is ruled by Spartacus. See the ","position":{"start":{"line":36,"column":1},"end":{"line":36,"column":1}},"key":"xgzp0AoHhP"},{"type":"link","url":"https://gitlab.in2p3.fr/gaz-quantiques-lcf/puce/ciceroisa","position":{"start":{"line":36,"column":1},"end":{"line":36,"column":1}},"children":[{"type":"text","value":"CiceroIsa Project","position":{"start":{"line":36,"column":1},"end":{"line":36,"column":1}},"key":"kqjnxPycqB"}],"urlSource":"https://gitlab.in2p3.fr/gaz-quantiques-lcf/puce/ciceroisa","key":"Rpa0vRvfvz"},{"type":"text","value":" for more information.","position":{"start":{"line":36,"column":1},"end":{"line":36,"column":1}},"key":"vzHlg570k7"}],"key":"Qq3d1NR9a1"}],"number":1,"enumerator":"1","key":"le0ZRUuKqV"},{"type":"footnoteDefinition","identifier":"thanks-marc","label":"thanks-marc","position":{"start":{"line":36,"column":1},"end":{"line":36,"column":1}},"children":[{"type":"paragraph","position":{"start":{"line":38,"column":1},"end":{"line":38,"column":1}},"children":[{"type":"text","value":"I would like to thank a lot Marc for the sequencer. I think that our team did not paid the sequencer back, and as good accounts make good friends, I guess we should... But OK, this is permanent researcher business. Nevertheless, in general, I think this illustrates the atmosphere of cooperation among the six research teams within the group, which I have been able to benefit from throughout my thesis. The credit for this good atmosphere goes to all the permanent researcher staff, whom I thank for it.","position":{"start":{"line":38,"column":1},"end":{"line":38,"column":1}},"key":"qXmT6oCQ03"}],"key":"P5MvC6MYrD"}],"number":3,"enumerator":"3","key":"GqiROPrmzA"},{"type":"footnoteDefinition","identifier":"wien-group","label":"wien-group","position":{"start":{"line":38,"column":1},"end":{"line":38,"column":1}},"children":[{"type":"paragraph","position":{"start":{"line":40,"column":1},"end":{"line":40,"column":1}},"children":[{"type":"text","value":"The Adwin labScript driver developed within the ","position":{"start":{"line":40,"column":1},"end":{"line":40,"column":1}},"key":"jlEJWxP2BU"},{"type":"link","url":"https://www.quantuminfo.at/","position":{"start":{"line":40,"column":1},"end":{"line":40,"column":1}},"children":[{"type":"text","value":"Leonard Lab","position":{"start":{"line":40,"column":1},"end":{"line":40,"column":1}},"key":"p6dCJUGJdp"}],"urlSource":"https://www.quantuminfo.at/","key":"k8eB8i7eL9"},{"type":"text","value":" can be found ","position":{"start":{"line":40,"column":1},"end":{"line":40,"column":1}},"key":"nBH2t1ZR2f"},{"type":"link","url":"https://gitlab.tuwien.ac.at/quantuminfo/experiment-control/labscript-userlib/leolab_devices","position":{"start":{"line":40,"column":1},"end":{"line":40,"column":1}},"children":[{"type":"text","value":"here","position":{"start":{"line":40,"column":1},"end":{"line":40,"column":1}},"key":"z9UtiFl7C8"}],"urlSource":"https://gitlab.tuwien.ac.at/quantuminfo/experiment-control/labscript-userlib/leolab_devices","key":"YtNw6WjPhM"},{"type":"text","value":" and was implemented by ","position":{"start":{"line":40,"column":1},"end":{"line":40,"column":1}},"key":"IEV09oeOYo"},{"type":"cite","identifier":"schabbauer_experiment_2023","label":"schabbauer_experiment_2023","kind":"narrative","position":{"start":{"line":40,"column":228},"end":{"line":40,"column":255}},"children":[{"type":"text","value":"Schabbauer (2023)","key":"VVKRFErhbJ"}],"enumerator":"7","key":"Ee5k4M4zWZ"},{"type":"text","value":".","position":{"start":{"line":40,"column":1},"end":{"line":40,"column":1}},"key":"kNVUp6SNcz"}],"key":"dj2JmSPPNv"}],"number":4,"enumerator":"4","key":"SgWUb0gPoP"},{"type":"footnoteDefinition","identifier":"access-online","label":"access-online","position":{"start":{"line":40,"column":1},"end":{"line":40,"column":1}},"children":[{"type":"paragraph","position":{"start":{"line":42,"column":1},"end":{"line":42,"column":1}},"children":[{"type":"text","value":"Even though the code is shared under the ","position":{"start":{"line":42,"column":1},"end":{"line":42,"column":1}},"key":"FaLDtEftkA"},{"type":"link","url":"https://www.gnu.org/licenses/gpl-3.0.en.html","position":{"start":{"line":42,"column":1},"end":{"line":42,"column":1}},"children":[{"type":"text","value":"GNU GPL3 free software","position":{"start":{"line":42,"column":1},"end":{"line":42,"column":1}},"key":"uBc78W37bF"}],"urlSource":"https://www.gnu.org/licenses/gpl-3.0.en.html","key":"zdzu9MjecD"},{"type":"text","value":" license, one needs to request access each year to the maintained repository on the ","position":{"start":{"line":42,"column":1},"end":{"line":42,"column":1}},"key":"gB2XpntG1g"},{"type":"link","url":"https://gitlab.mpcdf.mpg.de/qcontrol3","position":{"start":{"line":42,"column":1},"end":{"line":42,"column":1}},"children":[{"type":"text","value":"MPQ Gitlab server","position":{"start":{"line":42,"column":1},"end":{"line":42,"column":1}},"key":"KTXvh9bnaM"}],"urlSource":"https://gitlab.mpcdf.mpg.de/qcontrol3","key":"HTFe11sNTx"},{"type":"text","value":" which does not help the collaboration.","position":{"start":{"line":42,"column":1},"end":{"line":42,"column":1}},"key":"BYGowXn6Il"}],"key":"RgbS83VkN7"}],"number":8,"enumerator":"8","key":"E6MSfc69cU"},{"type":"footnoteDefinition","identifier":"pip_install","label":"pip_install","position":{"start":{"line":42,"column":1},"end":{"line":42,"column":1}},"children":[{"type":"paragraph","position":{"start":{"line":601,"column":1},"end":{"line":601,"column":1}},"children":[{"type":"text","value":"To install a package, one should clone it from the git repository, change to directory and install it as a developper :","position":{"start":{"line":601,"column":1},"end":{"line":601,"column":1}},"key":"dilDHOtXq9"},{"type":"inlineCode","value":"python setup.py develop","position":{"start":{"line":601,"column":1},"end":{"line":601,"column":1}},"key":"zaY0WR8mjl"},{"type":"text","value":". This means that rather than copying the package’s files into the site-packages directory (as it would with a regular installation), it creates a symbolic link or .pth file that points to the project’s source code directory. This enables you to modify the source code and the changes will take effect without the need for reinstallation (","position":{"start":{"line":601,"column":1},"end":{"line":601,"column":1}},"key":"BccbNtcpSE"},{"type":"emphasis","position":{"start":{"line":601,"column":1},"end":{"line":601,"column":1}},"children":[{"type":"text","value":"i.e.","position":{"start":{"line":601,"column":1},"end":{"line":601,"column":1}},"key":"ykFkg1Lt1P"}],"key":"S8njLwRfci"},{"type":"text","value":" running again the setup file installing again). Note also that I recommand to use the ","position":{"start":{"line":601,"column":1},"end":{"line":601,"column":1}},"key":"YVjPB8ez58"},{"type":"inlineCode","value":"python setup.py develop","position":{"start":{"line":601,"column":1},"end":{"line":601,"column":1}},"key":"GYLT5jBkpM"},{"type":"text","value":" command rather than the ","position":{"start":{"line":601,"column":1},"end":{"line":601,"column":1}},"key":"PYhw0kC542"},{"type":"inlineCode","value":"pip install -e .","position":{"start":{"line":601,"column":1},"end":{"line":601,"column":1}},"key":"lCgbE9FkDs"},{"type":"text","value":". Indeed, depending on which command we used to install the package, the ","position":{"start":{"line":601,"column":1},"end":{"line":601,"column":1}},"key":"XQRdUYv3Jb"},{"type":"inlineCode","value":"qcontrol3-create-package","position":{"start":{"line":601,"column":1},"end":{"line":601,"column":1}},"key":"M9tXJ1vruc"},{"type":"text","value":" that we use after in the tutorial did not worked. See the Laboratory Journal on the 06/10/23 for more informations.","position":{"start":{"line":601,"column":1},"end":{"line":601,"column":1}},"key":"ejBAqs164u"}],"key":"GFxRf8ERtX"}],"number":10,"enumerator":"10","key":"fBqFLFECEC"},{"type":"footnoteDefinition","identifier":"name-server","label":"name-server","position":{"start":{"line":601,"column":1},"end":{"line":601,"column":1}},"children":[{"type":"paragraph","position":{"start":{"line":603,"column":1},"end":{"line":603,"column":1}},"children":[{"type":"text","value":"The code to launch the name server (or the event-server) is ","position":{"start":{"line":603,"column":1},"end":{"line":603,"column":1}},"key":"mtiynB3DiI"},{"type":"inlineCode","value":"(qc3-env) $ name-server","position":{"start":{"line":603,"column":1},"end":{"line":603,"column":1}},"key":"bCJTLsCWMs"},{"type":"text","value":" where, the ","position":{"start":{"line":603,"column":1},"end":{"line":603,"column":1}},"key":"Jc3TCzbzSl"},{"type":"inlineCode","value":"(qc3-env)","position":{"start":{"line":603,"column":1},"end":{"line":603,"column":1}},"key":"GXbkglvxWZ"},{"type":"text","value":" keyword highlights that one must works within your favourite environment but will be dropped after.","position":{"start":{"line":603,"column":1},"end":{"line":603,"column":1}},"key":"aEFDfoRmrd"}],"key":"MfJdv6gySn"}],"number":12,"enumerator":"12","key":"m4qB99LLk3"},{"type":"footnoteDefinition","identifier":"2","label":"2","position":{"start":{"line":603,"column":1},"end":{"line":603,"column":1}},"children":[{"type":"paragraph","position":{"start":{"line":607,"column":1},"end":{"line":607,"column":1}},"children":[{"type":"text","value":"Note that you could have an error if you do not have yet entered your hardware configuration. If so, continue to next subsection and run again the ","position":{"start":{"line":607,"column":1},"end":{"line":607,"column":1}},"key":"zfRditE7lf"},{"type":"inlineCode","value":"event-server","position":{"start":{"line":607,"column":1},"end":{"line":607,"column":1}},"key":"apzGM8u7St"},{"type":"text","value":".","position":{"start":{"line":607,"column":1},"end":{"line":607,"column":1}},"key":"BFwCmYajxq"}],"key":"MQm5UOj4Dg"}],"number":2,"enumerator":"2","key":"dFa4PDRSxi"},{"type":"footnoteDefinition","identifier":"user_channel_name","label":"user_channel_name","position":{"start":{"line":607,"column":1},"end":{"line":607,"column":1}},"children":[{"type":"paragraph","position":{"start":{"line":609,"column":1},"end":{"line":609,"column":1}},"children":[{"type":"text","value":"The name of the channel must be composed of caps, number and “_”. Note that it is in the qc3 documentation that “the convention is that this is all upper case with a number at the end if appropriate. This number indexes several channels of the same kind and starts with 0.”","position":{"start":{"line":609,"column":1},"end":{"line":609,"column":1}},"key":"lNUgu8oSJW"}],"key":"tTamrnP5CU"}],"number":13,"enumerator":"13","key":"l6xPitCsy4"},{"type":"footnoteDefinition","identifier":"5","label":"5","position":{"start":{"line":609,"column":1},"end":{"line":609,"column":1}},"children":[{"type":"paragraph","position":{"start":{"line":614,"column":1},"end":{"line":614,"column":1}},"children":[{"type":"text","value":"The type of the value depends on the timing type : it is a boolean for a ","position":{"start":{"line":614,"column":1},"end":{"line":614,"column":1}},"key":"npJ581Oo63"},{"type":"inlineCode","value":"TimingChannelBool","position":{"start":{"line":614,"column":1},"end":{"line":614,"column":1}},"key":"IF4TPlwKuT"},{"type":"text","value":", like Digital outputs of the sequencer. To understand deeper the different type of TimingChannel and user channel, I would recommend to create from scratch a ","position":{"start":{"line":614,"column":1},"end":{"line":614,"column":1}},"key":"eT5V3iBRKw"},{"type":"emphasis","position":{"start":{"line":614,"column":1},"end":{"line":614,"column":1}},"children":[{"type":"text","value":"remote device","position":{"start":{"line":614,"column":1},"end":{"line":614,"column":1}},"key":"zYY5nolI8O"}],"key":"V4E7EFNyqE"},{"type":"text","value":" following the subsection - a ","position":{"start":{"line":614,"column":1},"end":{"line":614,"column":1}},"key":"sqY8Tf3OYQ"},{"type":"emphasis","position":{"start":{"line":614,"column":1},"end":{"line":614,"column":1}},"children":[{"type":"text","value":"Timing Device","position":{"start":{"line":614,"column":1},"end":{"line":614,"column":1}},"key":"og2BOqH0sH"}],"key":"i66c7YMkZR"},{"type":"text","value":" composed of several type of Timing Channels in qc3 terminology.","position":{"start":{"line":614,"column":1},"end":{"line":614,"column":1}},"key":"lwQhqwGoBm"}],"key":"ZD9qifAFbt"}],"number":5,"enumerator":"5","key":"JiAjWLzMbx"},{"type":"footnoteDefinition","identifier":"6","label":"6","position":{"start":{"line":614,"column":1},"end":{"line":614,"column":1}},"children":[{"type":"paragraph","position":{"start":{"line":616,"column":1},"end":{"line":616,"column":1}},"children":[{"type":"text","value":"Note that several remote controllers can be launched. To do so, one just have to create a new directory with a ","position":{"start":{"line":616,"column":1},"end":{"line":616,"column":1}},"key":"u5KGHk1x2R"},{"type":"inlineCode","value":"config.py","position":{"start":{"line":616,"column":1},"end":{"line":616,"column":1}},"key":"RnuH2OdIxw"},{"type":"text","value":" file and declare the path to this directory and the name of this remote in ","position":{"start":{"line":616,"column":1},"end":{"line":616,"column":1}},"key":"c8x6aVah0Y"},{"type":"inlineMath","value":"\\sim","position":{"start":{"line":616,"column":1},"end":{"line":616,"column":1}},"html":"<span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mo>∼</mo></mrow><annotation encoding=\"application/x-tex\">\\sim</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:0.3669em;\"></span><span class=\"mrel\">∼</span></span></span></span>","key":"BP0iJZfmRx"},{"type":"inlineCode","value":"/.qc3/qc3conf.json","position":{"start":{"line":616,"column":1},"end":{"line":616,"column":1}},"key":"VGHbcfrnu8"},{"type":"text","value":".","position":{"start":{"line":616,"column":1},"end":{"line":616,"column":1}},"key":"HwC3LIcrGi"}],"key":"MGX8x7JxZr"}],"number":6,"enumerator":"6","key":"aR08697lQs"},{"type":"footnoteDefinition","identifier":"7","label":"7","position":{"start":{"line":616,"column":1},"end":{"line":616,"column":1}},"children":[{"type":"paragraph","position":{"start":{"line":618,"column":1},"end":{"line":618,"column":1}},"children":[{"type":"text","value":"It is recommended to install this package as a developer (","position":{"start":{"line":618,"column":1},"end":{"line":618,"column":1}},"key":"xmyy7NA999"},{"type":"inlineCode","value":"python meteo_driver/setup.py develop","position":{"start":{"line":618,"column":1},"end":{"line":618,"column":1}},"key":"ZqKSgADW2p"},{"type":"text","value":"). Doing so, the installation process will create symbolic links that point to your driver software so that any modification in your driver does not need a new installation in your environment.","position":{"start":{"line":618,"column":1},"end":{"line":618,"column":1}},"key":"TZfNz5UaiN"}],"key":"bJQvJZ50Tw"}],"number":7,"enumerator":"7","key":"PL1tC86zii"},{"type":"footnoteDefinition","identifier":"9","label":"9","position":{"start":{"line":618,"column":1},"end":{"line":618,"column":1}},"children":[{"type":"paragraph","position":{"start":{"line":622,"column":1},"end":{"line":622,"column":1}},"children":[{"type":"text","value":"The default repository is ","position":{"start":{"line":622,"column":1},"end":{"line":622,"column":1}},"key":"VxHESrfejV"},{"type":"inlineMath","value":"\\sim","position":{"start":{"line":622,"column":1},"end":{"line":622,"column":1}},"html":"<span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mo>∼</mo></mrow><annotation encoding=\"application/x-tex\">\\sim</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:0.3669em;\"></span><span class=\"mrel\">∼</span></span></span></span>","key":"LX9UM0MNr5"},{"type":"inlineCode","value":"/qc3remotecontroller0/","position":{"start":{"line":622,"column":1},"end":{"line":622,"column":1}},"key":"YhTlzyIHWk"},{"type":"text","value":" with default name being ","position":{"start":{"line":622,"column":1},"end":{"line":622,"column":1}},"key":"tQwf3P3gQA"},{"type":"inlineCode","value":"REMOTE0","position":{"start":{"line":622,"column":1},"end":{"line":622,"column":1}},"key":"CJJAXMvG5d"}],"key":"nelJ5SidqA"}],"number":9,"enumerator":"9","key":"U9gkXxPMyN"},{"type":"footnoteDefinition","identifier":"rappel-lancement-remote-server","label":"rappel-lancement-remote-server","position":{"start":{"line":622,"column":1},"end":{"line":622,"column":1}},"children":[{"type":"paragraph","position":{"start":{"line":627,"column":1},"end":{"line":627,"column":1}},"children":[{"type":"text","value":"to launch the remote0 server, one must run ","position":{"start":{"line":627,"column":1},"end":{"line":627,"column":1}},"key":"zdqhmb18Uq"},{"type":"inlineCode","value":"$ qcontrol3-remoteserver REMOTE0","position":{"start":{"line":627,"column":1},"end":{"line":627,"column":1}},"key":"ZKYCErcC1K"}],"key":"zZBdhUQlTu"}],"number":14,"enumerator":"14","key":"OqpRd2Yhjq"},{"type":"footnoteDefinition","identifier":"sequence_parameter_loading","label":"sequence_parameter_loading","position":{"start":{"line":627,"column":1},"end":{"line":627,"column":1}},"children":[{"type":"paragraph","position":{"start":{"line":605,"column":1},"end":{"line":605,"column":1}},"children":[{"type":"text","value":"For example, the dictionary entry string ","position":{"start":{"line":605,"column":1},"end":{"line":605,"column":1}},"key":"AZYhPktXXo"},{"type":"inlineCode","value":"\"3 V\"","position":{"start":{"line":605,"column":1},"end":{"line":605,"column":1}},"key":"rH1RbpAiIz"},{"type":"text","value":" will be changed to ","position":{"start":{"line":605,"column":1},"end":{"line":605,"column":1}},"key":"vizNphszUQ"},{"type":"inlineCode","value":"3 * u.V","position":{"start":{"line":605,"column":1},"end":{"line":605,"column":1}},"key":"KgSLh8lqsu"},{"type":"text","value":", a qunits quantity.","position":{"start":{"line":605,"column":1},"end":{"line":605,"column":1}},"key":"uPyexHDSg6"}],"key":"NiwidJjwLa"}],"number":15,"enumerator":"15","key":"C6i8jDqDky"},{"type":"footnoteDefinition","identifier":"iter_step_values","label":"iter_step_values","position":{"start":{"line":605,"column":1},"end":{"line":605,"column":1}},"children":[{"type":"paragraph","position":{"start":{"line":611,"column":1},"end":{"line":611,"column":1}},"children":[{"type":"text","value":"When the ","position":{"start":{"line":611,"column":1},"end":{"line":611,"column":1}},"key":"uRN7mpxtqY"},{"type":"inlineCode","value":"pys","position":{"start":{"line":611,"column":1},"end":{"line":611,"column":1}},"key":"cdCUxfwcnS"},{"type":"text","value":" file is uploaded, it is parsed and exectuted a first time with iter_step value ","position":{"start":{"line":611,"column":1},"end":{"line":611,"column":1}},"key":"L4GV9NxThX"},{"type":"inlineCode","value":"-1","position":{"start":{"line":611,"column":1},"end":{"line":611,"column":1}},"key":"df85TxUmnm"},{"type":"text","value":". The file is then executed at each run with iter_step increasing value ranging from 0 to the length of the iter_list minus one.","position":{"start":{"line":611,"column":1},"end":{"line":611,"column":1}},"key":"DkWtf6oRTu"}],"key":"YRsNOmZj9i"}],"number":16,"enumerator":"16","key":"WC0FbjNxhD"},{"type":"footnoteDefinition","identifier":"11","label":"11","position":{"start":{"line":611,"column":1},"end":{"line":611,"column":1}},"children":[{"type":"paragraph","position":{"start":{"line":539,"column":1},"end":{"line":539,"column":1}},"children":[{"type":"text","value":"This problem is also because of the software we used needed to open all file at once, which is not optimized.","position":{"start":{"line":539,"column":1},"end":{"line":539,"column":1}},"key":"qXgx76suz1"}],"key":"AWbgBJyh8w"}],"number":11,"enumerator":"11","key":"rZp7fjROKU"},{"type":"footnoteDefinition","identifier":"scan-origin","label":"scan-origin","position":{"start":{"line":539,"column":1},"end":{"line":539,"column":1}},"children":[{"type":"paragraph","position":{"start":{"line":583,"column":1},"end":{"line":583,"column":1}},"children":[{"type":"text","value":"At first, we used to define within the code the parameters valueas well as the scanned parameters so in order to have a smooth implementation, this code was thought to be compatible with the way we used to work.","position":{"start":{"line":583,"column":1},"end":{"line":583,"column":1}},"key":"EsgShJ0vVE"}],"key":"n1QzR8xDPJ"}],"number":17,"enumerator":"17","key":"rXrTLuV21E"},{"type":"footnoteDefinition","identifier":"scan_save_values","label":"scan_save_values","position":{"start":{"line":583,"column":1},"end":{"line":583,"column":1}},"children":[{"type":"paragraph","position":{"start":{"line":584,"column":1},"end":{"line":584,"column":1}},"children":[{"type":"text","value":"All parameter values are saved at each run, but since only a small fraction of them are of particular interest for the immediate analysis, we store them in a dedicated file.","position":{"start":{"line":584,"column":1},"end":{"line":584,"column":1}},"key":"fBDqF58pOd"}],"key":"eekQW4EoAR"}],"number":18,"enumerator":"18","key":"iOsub52Klv"}],"key":"FEJL9K8kbW"}],"key":"uvskM98ytF"},"references":{"cite":{"order":["raven_new_2022","keshet_distributed_2013","starkey_scripted_2013","sayrin_real_time_2011","darsow_fromm_nqontrol_2020","marolleau_quantum_2022","schabbauer_experiment_2023"],"data":{"raven_new_2022":{"label":"raven_new_2022","enumerator":"1","html":"Raven, H. von. (2022). <i>A new Caesium quantum gas microscope with precise magnetic field control</i> [Phdthesis]. Ludwig-Maximilians-Universität München."},"keshet_distributed_2013":{"label":"keshet_distributed_2013","enumerator":"2","doi":"10.1063/1.4773536","html":"Keshet, A., & Ketterle, W. (2013). A Distributed GUI-based Computer Control System for Atomic Physics Experiments. <i>Review of Scientific Instruments</i>, <i>84</i>(1), 015105. <a target=\"_blank\" rel=\"noreferrer\" href=\"https://doi.org/10.1063/1.4773536\">10.1063/1.4773536</a>","url":"https://doi.org/10.1063/1.4773536"},"starkey_scripted_2013":{"label":"starkey_scripted_2013","enumerator":"3","doi":"10.1063/1.4817213","html":"Starkey, P. T., Billington, C. J., Johnstone, S. P., Jasperse, M., Helmerson, K., Turner, L. D., & Anderson, R. P. (2013). A scripted control system for autonomous hardware timed experiments. <i>Review of Scientific Instruments</i>, <i>84</i>(8), 085111. <a target=\"_blank\" rel=\"noreferrer\" href=\"https://doi.org/10.1063/1.4817213\">10.1063/1.4817213</a>","url":"https://doi.org/10.1063/1.4817213"},"sayrin_real_time_2011":{"label":"sayrin_real_time_2011","enumerator":"4","doi":"10.1038/nature10376","html":"Sayrin, C., Dotsenko, I., Zhou, X., Peaudecerf, B., Rybarczyk, T., Gleyzes, S., Rouchon, P., Mirrahimi, M., Amini, H., Brune, M., Raimond, J.-M., & Haroche, S. (2011). Real-time quantum feedback prepares and stabilizes photon number states. <i>Nature</i>, <i>477</i>(7362), 73–77. <a target=\"_blank\" rel=\"noreferrer\" href=\"https://doi.org/10.1038/nature10376\">10.1038/nature10376</a>","url":"https://doi.org/10.1038/nature10376"},"darsow_fromm_nqontrol_2020":{"label":"darsow_fromm_nqontrol_2020","enumerator":"5","doi":"10.1063/1.5135873","html":"Darsow-Fromm, C., Dekant, L., Grebien, S., Schröder, M., Schnabel, R., & Steinlechner, S. (2020). NQontrol: An open-source platform for digital control-loops in quantum-optical experiments. <i>Review of Scientific Instruments</i>, <i>91</i>(3), 035114. <a target=\"_blank\" rel=\"noreferrer\" href=\"https://doi.org/10.1063/1.5135873\">10.1063/1.5135873</a>","url":"https://doi.org/10.1063/1.5135873"},"marolleau_quantum_2022":{"label":"marolleau_quantum_2022","enumerator":"6","html":"Marolleau, Q. (2022). <i>Quantum atom optics with metastable helium atoms</i> [Phdthesis]. Université Paris-Saclay."},"schabbauer_experiment_2023":{"label":"schabbauer_experiment_2023","enumerator":"7","html":"Schabbauer, J. (2023). <i>Experiment control for quantum simulation with non-local interactions</i> [Phdthesis, Vienna University of Technology]. <a target=\"_blank\" rel=\"noreferrer\" href=\"https://web.archive.org/web/20230602133552id_/https://repositum.tuwien.at/bitstream/20.500.12708/175698/1/Schabbauer%20Johannes%20-%202023%20-%20Experiment%20control%20for%20quantum%20simulation%20with...pdf\">https://web.archive.org/web/20230602133552id_/https://repositum.tuwien.at/bitstream/20.500.12708/175698/1/Schabbauer%20Johannes%20-%202023%20-%20Experiment%20control%20for%20quantum%20simulation%20with...pdf</a>","url":"https://web.archive.org/web/20230602133552id_/https://repositum.tuwien.at/bitstream/20.500.12708/175698/1/Schabbauer%20Johannes%20-%202023%20-%20Experiment%20control%20for%20quantum%20simulation%20with...pdf"}}}},"footer":{"navigation":{"prev":{"title":"General appendix","short_title":"General appendix","url":"/appendix-generalities","group":"On the entanglement of quasi-particles in a Bose-Einstein condensate"},"next":{"title":"Technical details about the experiment","short_title":"Technical notes","url":"/technical-notes","group":"On the entanglement of quasi-particles in a Bose-Einstein condensate"}}},"domain":"http://localhost:3011"}