{"id":1216,"date":"2024-08-31T15:10:02","date_gmt":"2024-08-31T14:10:02","guid":{"rendered":"https:\/\/www.skynext.tech\/?p=1216"},"modified":"2025-08-20T14:23:45","modified_gmt":"2025-08-20T13:23:45","slug":"geiger-muller-counter-interfacing-with-raspberry-pi","status":"publish","type":"post","link":"https:\/\/www.skynext.tech\/index.php\/2024\/08\/31\/geiger-muller-counter-interfacing-with-raspberry-pi\/","title":{"rendered":"Geiger-Muller counter interfacing with Raspberry Pi."},"content":{"rendered":"\n<figure class=\"wp-block-table\"><table><tbody><tr><td>Article updated the 20th of August 2025, reflecting the recent analysis of GPIO performance of Raspberry Pi in user space contexts and Python, vs kernel based contexts using GPIOd_* functions or MMIO, and the suitability of Linux Industrial IO subsystem for such endeavours.<br>DUT pictures were added.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>When interfacing a Geiger-Muller device with a MCU or a Raspberry pi, there are mainly two options available :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Use of a high level device, which transfers counter information digitally such as cps, cpm, tube type, stored memory or whatever information the device holds. Some devices may also be able to inform the host of a pulse detection using a low level signaling mode, and perform as a low level device. High level devices may be more or less sophisticated and allow for calibration, unit conversions, dosimetry, or changing settings depending on the tube model and their efficiency characteristics. High count compensation due to dead time may or may not be done, but any serious device should perform such processing. The compensation formulas are dependent on the designer knowledge of the matter and their proprietary choices.<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Use of a low level device. Such a device is an analog front end that supplies high voltage to the GM tube, and outputs detected events as pulses on a GPIO pin. The short pulse is usually stretched to a fixed time pulse, with sharp rising and falling edges. It should essentially output a square wave signal, that is easily processed by subsequent A\/D stages that are not part of the device itself. Signal output is commonly done via GPIO header pins and\/or 3.5 audio jacks. Most also feature a buzzer for direct audio pulse output.<\/li>\n<\/ul>\n\n\n\n<p><strong>This article is focused on the low level devices and their interfacing with a digital counting platform such as the Raspberry Pi<\/strong>, <strong>as it offers maximum processing flexibility<\/strong> <strong>and straightforward interfacing. but<\/strong> <strong>for low count rates only.<\/strong><\/p>\n\n\n\n<p>Note that for high CPM processing, digital latency effects starts to be significative when using a non real-time OS platform due to operating system overhead (kernel scheduling &amp; pre-emption). Part of this article will deal with mitigation of these unwanted effects.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">GM Tube basics.<\/h3>\n\n\n\n<p>There are plenty of resources explaining the physics of the GM Tube. We won&#8217;t cover them in detail except for the important issue of dead time and how this skew the measured count rate at high levels of ionizing radiation (high count rates). This issue is critical as the device underestimates the count at these regimes. That is, the device is not linear.<br><br>The GM Tube is supplied a high enough voltage to work in the Geiger plateau, such as an ionization event triggers a Townsend avalanche and a significant charge is displaced between anode and cathode, and this is seen by the amplifier (either a transistor or an op-amp) as a voltage pulse. This charge displacement is equivalent to a lowering of the impedance of the GM Tube, which induces a voltage drop from the nominal high voltage, as the high voltage source is far from ideal, it can&#8217;t source much current and has added resistors. The GM tube and resistors on the high voltage path perform as a voltage divider (with a parallel path to ground, the GM tube &#8211; with its impedance lowering during the Townsend avalanche process)<\/p>\n\n\n\n<p>This voltage drop is conditioned to a low voltage (with reference to ground), buffered, and the pulse is stretched to several hundreds of microseconds to a couple of milliseconds, depending on the design and\/or tuning.<br>Pulse stretching usually involves stages such as Schmitt triggers and 555 timers<br><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Dead time from the analog front end.<\/h3>\n\n\n\n<p><br>Usually the analog front end circuitry processing exhibits a<strong> non-paralyzable dead-time <\/strong>characteristic.<\/p>\n\n\n\n<p><br><strong>dead time : <\/strong>it means that after a pulse is detected by this front end, any subsequent pulse is not detected during the interval spanning from the registered pulse to the expiration of the dead-time (the pulse stretched &#8220;HIGH&#8217; state time, set usually by an analog timer such as a 555.)<\/p>\n\n\n\n<p><strong>non-paralyzable :<\/strong> it means that any townsend avalanche event occuring during that dead-time interval. <strong>does not <\/strong>re-trigger the dead time, or at least, it should not. If it does, it would be a poor design choice as dead-time from any processing stage should be minimized as much as possible, and a paralyzable dead-time may extend this duration.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">GM Tube intrinsic dead time.<\/h3>\n\n\n\n<p><br>As for the GM tube Townsend avalanche process, it has an intrinsic dead time characteristic that is short but still significative. After a sucessful ionizing event detection, one that triggers a full Townsend avalanche, the tube is unable to detect any other event during the dead time. This dead time is usually in the order of 80 to 200 \u00b5s, and is mostly <strong>paralyzable <\/strong>: Any event ocurring during that dead time, resets that intrinsic dead time to some extent. For sake of simplicity, we will treat it as a fully paralyzable dead time. In reality, most of the literature agrees that this intrinsic dead time falls in between a paralyzable and non paralyzable model.<br><br>We make the supposition that the dead time is a function of the time separation of two subsequent (or more) ionization events, with the limit reaching the nominal dead time as event separation in the time domain goes toward infinity.<br>The precise model of a Townsend avalanche and its practical implementation in a commercial GM tube is outside of the scope of this article.<\/p>\n\n\n\n<p>Thus it follows that the dead-time nominal values from the GM Tube and those of the analog pulse stretch front end are important parameters for count rate compensation.<br><br>Analog front end deadtime measurement is quite straightforward in a low count (low background radiation) environment, and can be done by plugging the GM meter jack output to a sound card set at the highest sampling capability, ideally 96ks\/s or more. Or better, by using an oscilloscope.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">GM Module used for our tests<\/h3>\n\n\n\n<p>The following device is widely available on Chinese marketplaces, fully mounted, for around 15 to 20 EUR. It bears the PCB designer silkscreen marking &#8220;RadiationD V.1.1(CAJOE)&#8221;. It uses two DIP8 555 timers, and one LM358 op-amp.The provided GM tube is a Chinese J305Pr. The three IC are mounted on sockets, allowing for easy replacement. A simple mod could allow tuning the pulse stretching time of the analog front end for better performance in high pulse count environments and for MCU\/SOC event processing, at the expense of the audio cue jack output.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"661\" height=\"536\" src=\"https:\/\/www.skynext.tech\/wp-content\/uploads\/2024\/08\/GM_module_1_1_CAJOE.png\" alt=\"\" class=\"wp-image-1560\"\/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\"><br>Analog front end and audio cue CPM\/CPS monitoring considerations<\/h3>\n\n\n\n<p>With that DUT in mind, the front end deadtime (the stretched pulse width) was measured at around <strong>2.2ms on average<\/strong>. The reason for such a long deadtime is that it is intended to be processed by the human ear system, a too short pulse would lead to deficient audio cue for low pulse counts such as background radiation monitoring. For high pulse counts, the saturation to constant &#8220;high&#8221; level from such long pulses piling up would render audio cue high pulse count monitoring ineffective and dangerous, as saturation would provide a constant high level logic output. That is DC and it is converted to a silent state by any speaker or headphone.<\/p>\n\n\n\n<p><strong>That is why a good analog front end used to generate an audio cue signal would use a charge pump pulse to variable voltage conversion stage, such as an LM3907\/LM2917 and a VCO to generate an audio tone whose frequency is dependent on the integrated pulse count over n last seconds<\/strong>. A common value for n would be 1 or 60 or more (infinity integration and resettable) for &#8220;dosimetric&#8221; readings. The integration range could be switch selectable. The transfer function of the VCO (V to f) should be carefully designed so as to provide good audio cues for low up to high count rates, taking into account frequency cut-off of the human ear for older subjects.<\/p>\n\n\n\n<p>The two extreme points on the CPM transfer function (60s integration) could be in the ballpark of :<\/p>\n\n\n\n<p>20 CPM -> 50 Hz<\/p>\n\n\n\n<p>50000 CPM -> 4kHz.<\/p>\n\n\n\n<p>With amplitude compensation accounting for the human ear psychoacoustics, which decrease the sensitivity to high frequency tones and taking into account the risk of ear damage.<\/p>\n\n\n\n<p>A superimposed alarm tone should be used above 50000 CPM to warn the user of unreliable count estimation.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">DUT J305Pr intrinsic dead time<\/h3>\n\n\n\n<p>As for the intrinsic dead time of a given GM Tube, some are reported in datasheets as an estimation. We could not find one for the J305Pr. Determination of that dead time is not an easy task, in part because the ionization events exhibit a probabilistic distribution (modeled as a Poisson process) &#8211; That is, it is hard to control the precise moment when a ionization event will trigger a Townsend avalanche, and relative time to the next incoming gamma-ray or alpha\/beta particle that would trigger an avalanche. Best to err to the side of caution and assume a 200 \u00b5s intrinsic dead time.<\/p>\n\n\n\n<p>Furthermore, GM Tubes have an efficiency parameter: Of all the gamma flux that intercepts the section area of the tube (usually the tube length times the tube diameter, and taking into account the mass absorption characteristics of the tube wall due to limb effects if one wants a really precise characterization), not all gamma flux will interact with the tube gas electrons, the main factors to take into account are the finite &#8211; and small &#8211; tube volume, low gas density, and type of gas used as it influences ionization behaviour. Note that GM tubes are sensitive to x-ray (with quite low efficiency) gamma rays, and charged particles such as alpha, beta+ and beta-. Non charged particles such as neutrons are detected indirectly, by a nuclear process that give rise to charged particles when a neutron is captured or absorbed by the GM tube gas. Neutron sensitive GM tubes may use BF3 gas (Boron Tri-Fluoride)<\/p>\n\n\n\n<p><strong>GM Tube efficiency<\/strong><\/p>\n\n\n\n<p>Common beta\/gamma small glass tubes exhibit an efficiency of <strong>around 0.03<\/strong><\/p>\n\n\n\n<p>Moreover, this efficiency varies with the gamma ray energy. It is well known that GM Tubes under-perform in the X-ray spectrum. Flattening of the energy\/efficiency response curve can be done by using filters (such as thin metal sheets) that partially occult the tube, mainly for gamma counting.<\/p>\n\n\n\n<p>As for tubes that exhibit a better sensitivity in the alpha and beta detection mode, they usually are made with walls that have a lower extinction coefficient for alpha or beta particle, such as mica.<\/p>\n\n\n\n<p>Remember also that GM tubes are not proportional counters, scintillators, or particles chambers. They do not convey information about the eV energy of the initial particle, as the Townsend avalanche &#8220;saturates&#8221; the detector.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">True count rate estimation based on GM tube dead time and analog front end dead time<\/h3>\n\n\n\n<p>Based on the research of Muller in &#8220;Dead Time problems&#8221; &#8211; Nuclear instruments and methods 112th issue (1973),  (1) The model we will use is stated on page 56 (d) equation (56), as it accounts for t<strong>wo dead times in series, <\/strong>one paralyzable from the GM tube, and one non-paralyzable from the analog front end (pulse stretcher)<\/p>\n\n\n\n<p>we can see that the analog dead time due to pulse shaping into a square wave is the limiting factor as for high counting rates. Thus, it is preferable to tune, in the design phase, the 555 timing to achieve the shortest pulse length that does not trigger spurious counts by the A\/D stage. A\/D stages typically register the rising edge of the pulse. As the amplitude of the pulse is not of any particular interest, a high frequency, low bit resolution A\/D design is preferable, such as a sigma\/delta ADC, (ADC considerations go beyond our scope, as we are limited by the BCM GPIO hardware on the Raspberry Pi) and good noise immunity practices, such as using shielding for the whole assembly and a shielded signal cable grounded at one end, or twisted pair, while maintaining the shortest possible signal path from the GM front end to the ADC. This is to ensure good signal integrity and low stray loop inductance. A very short pulse could induce ringing and be registered as multiple events when the level lingers between the low\/high logic boundary. However, there are diminishing returns for high count precision when the analog front end dead time approaches the intrinsic GM tube dead time, that is in the order or 80 to 200 \u00b5s. These time constants are well within the 555 timer capabilities, and proper design should take care of ringing artifacts. As for the hardware limitations of Raspberry pi pulse sensing, they are in the tens of ns range. Which means that lowering analog front-end dead time for ADC sensing to around 100 \u00b5s should not be a hardware limiting factor. As for the software GPIO \/ ISR library, it is recommended to use one that minimizes delay. Some libraries are implemented as linux daemons that may allow better management of high count rates. Best is to compare performance with a signal generator between the standard Python Raspberry Pi GPIO libraries that perform better with high pulse frequency (in the order of 10 kHz).<\/p>\n\n\n\n<p>Python code processing could be the bottleneck, if care is not taken to benchmark deque() performance at 10 kHz pulse rate, particularly if the deque() stores the pulse timing with calls to Python time libraries.<\/p>\n\n\n\n<p>Our recents tests on GPIO performance in user space context, show that a kernel space managed IRQ is better suited, and critical systems such as these would benefit from such a driver module for robustness, and could leverage the industrial IO linux subsystem, and its inherent buffers and trigger integrations.<\/p>\n\n\n\n<p>IRQ pinning to a specific core is highly recommended  to avoid pulse drops due to kernel scheduling and pre-emption, for non RT kernels. This would require at least a dual core SoC.<\/p>\n\n\n\n<p>For mission critical robustness and calibration, a MCU backend is preferable to provide hardware buffering of the count rate, which brings us to the initial considerations of this article, that is the need of real time pre-processing.<\/p>\n\n\n\n<p><strong>The calibration script effort as well as the counting script shown later in the article would thus need interfacing to a MCU (over serial or USB and through linux IIO) instead of relying on Python GPIO capabilities at high count rates, > 1k CPS, or at least, use GPIOd functions or MMIO\/polling or GPIO IRQ to detect rising and falling edges with a minimal kernel driver module efort. the Python frontend would then access the IIO device to get the CPS\/CPM count. The calibration script frontend would still be useful for jig positioning of the source. Assuming perfectly periodic events at a frequency of 1\/2*intrinsic_dead_time_max, that is 1\/400us, and neglecting analog front end dead time, the max count rate would be 2.5k CPS.<\/strong> <strong>That is already in hardware buffering territory or at least kernel space code.<\/strong><\/p>\n\n\n\n<p><strong>Note that Linux IIO provides timestamping information<\/strong>, which could be attached to the aggregated IRQ count per second or CPM, to allow for reconstruction of equispaced sample data through interpolation.<br><br>Also, registering the falling edge may be useful to assess proper operation of the GM analog front end. Absence of a falling edge in a timely manner before the next rising edge could signify that the signal is stuck in a high state, and should display a malfunction and\/or high count warning.<br><br>It is also preferable to use a micro controller or full fledged miniature computer such as a Raspberry pi with adequate processing power, which translates into a fast CPU clock and more than one core (for computers) to decrease ISR (interrupt service request) burden to a minimum in high count environment.<br><br>In the case of a Raspberry Pi, and when using Python, the following guidelines should be followed :<\/p>\n\n\n\n<p><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Minimum amount of code in the ISR.<\/li>\n\n\n\n<li>Ideally it should use a deque() for pulse registering, simply appending the pulse to the deque in the ISR, and exiting the ISR.<\/li>\n\n\n\n<li>Assessing the need for specialized GPIO libraries for pulse counting, such as those that involve a daemon, when pulse timestamping with the highest precision is a design requirement. In that case however, inter-process communication (IPC) delay is a factor to take into account for overall responsiveness.<\/li>\n\n\n\n<li>A separate thread on another core should perform post processing such as logging into the file-system or a database, or count rate compensation calculations.<\/li>\n\n\n\n<li>It is preferable to use a low level language such as C++ instead of Python, and precise benchmarking should be done using a function generator generating pulses with a comparable duty time to the GM pulse shaper backend, with increasing CPM frequency, to assess the digital latency induced and ISR responsiveness in high CPM environments. This way, the influence of the A\/D backend and code performance can be precisely factored in for final count up-rating &amp; device calibration.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Pulse time-stamping<\/h3>\n\n\n\n<p>In our design the deque() stores a timestamp for each pulse. Pulse time-stamping is a niche requirement and may be of use to triangulate the source of a sudden burst of gamma energy, although air attenuation coefficient factor coupled with poor efficiency of GM tubes, would render such an endeavour tricky. As for alpha and beta particle radiation, their detection on fixed position sensors for environmental monitoring in weather stations is dependent on wind and atmospheric currents drift that carry contaminated dust and fallout, which operate on timescales large enough to not require precise time stamping.<br><br>For EAS (extensive air shower) research arising from high energy cosmic particles, as well as study of dark lightning generated terrestiral gamma-ray flashes (TGF) a scintillation detector would be a better choice, as they have a better quantum yield.<br><br>A GPS module is a good investment in a project of this kind as it allows not only Geo tagging of events, but also precise timestamping due to inherent time synchronisation features of GPS.<br><br>Alternatively, low quality synchronisation of nodes that perform event timestamping may use NTP or higher precision NTP protocols. In any case, precise node time synchronisation using NTP requires symmetric network packet processing (no asymmetric routing &#8211; this creates different propagation delays upstream and downstream). These propagation delay uncertainties increase substantially when the time source is several router hops away, and also depend on the network traffic load induced delay.<br><br>If time synchronisation is performed through air (such as using Lora) all radio induced propagation delays and bitrate induced delays have to be factored in.<br><\/p>\n\n\n\n\n\n\n<h3 class=\"wp-block-heading\"><br>Count up-rating using two dead times in series model with time constants t1 and t2. <\/h3>\n\n\n\n<p><br>In our project, we will use Muller&#8217;s derivation (1) p56. (d)<br><br>$$ R = \\frac{\\rho}{(1-\\alpha)x} + e^{\\alpha x} $$<br><br>$$ x = \\rho t_{2} $$<br><br>$$ \\alpha = \\frac{t_{1}}{t_{2}} $$<br><br>$$ \\rho $$<\/p>\n\n\n\n<p>being the true count rate estimation, and<\/p>\n\n\n\n<p>$$ R $$<\/p>\n\n\n\n<p>being the measured count<br><br>$$ t_{1} $$<\/p>\n\n\n\n<p>being the (paralyzable) dead time of the GM Tube, and<\/p>\n\n\n\n<p>$$ t_{2} $$<\/p>\n\n\n\n<p>being the (non-paralyzable) dead time of the analog frontend pulse shaper.<br><br>Let&#8217;s introduce the other well known models accounting for a single dead time system:<br><br><strong>the non paralyzable model :<\/strong><\/p>\n\n\n\n<p>$$ R = \\frac{\\rho}{1 + t\\rho} $$<br><strong>the paralyzable model :<\/strong><\/p>\n\n\n\n<p>$$ R = \\rho e^{(-\\rho t)} $$<br><br>Since the unknown is the corrected count (rho), we need to use the inverse function of these models, regardless of the model, compound, paralyzable or non paralyzable.<br><br>The paralyzable function inverse expression requires the use of the W0 and W1 Lambert function, Math helpers in Python such as scipy allow straightforward calculation of the Lambert W0 and W1 branches, albeit with some computational burden.<br><br>The compound t1 and t2 in series requires numerical methods such as the secant method. Which would only increase the computational burden.<br><br>In the case of a Raspberry Pi, since RAM and storage are not an issue, and the problem is not multivariate since t1 and t2 are constants. We advise to compute the functions models, and use a reverse table lookup for fast determination of the corrected count. Scipy propose linear and higher order interpolation mechanisms, which would have a lower computational burden than root finding.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Calibration and experimental confirmation of the count correction model.<\/h3>\n\n\n\n<p><strong>Disclaimer :<\/strong> For this part, access to a medium activity point source &gt; 100 kBq, with low uncertainty is preferable. A low activity source would not push the GM counter at count rates where there is significant deviation from the true rate, and thus not give enough data to properly test the models. Depending on your location, point sources are exempt of declaration at different ceilings. To complicate things further, several regulations may overlap such as national \/ European Union, and providers of sources may or may not be available in your country. a source in the 100 kBq pretty much requires a license anywhere in the world. One option may be to use the source of a third party at the site of the third party licensed metrology \/ research lab. As always, exposure to a medium activity source may be harmful depending on exposure time and proper handling and shielding precautions are required.<\/p>\n\n\n\n<p>Besides the point source, a lead plated rectangular cross section channel spanning from the point source to the GM Tube is preferable, such a device function is not to serve as a collimator, but rather to prevent reflections of gamma rays leading to constructive \/ destructive interference, as some papers suggest. It seems quite remarkable however that such effects interfere significantly with the measurement, given the very low refractive index of most materials in the gamma spectrum. They would however shield the detector somewhat from background radiation and other sources that may be found in a lab at relative proximity.<\/p>\n\n\n\n<p>Note that a Cs137 nucleide decays either to a stable 56Ba137 nucleide through Beta- decay, with a probability of 5.4%, or to an excited (56Ba137m) state, also through Beta- decay, with a probability of 94.6%. When reverting to the ground state 56Ba137, some of the 56Ba137m nucleides emit a 0.6617 MeV gamma photon. Of all Cs137 decays that form the measure of the total activity of the sample supplied by the manufacturer, 85.1 % yield gamma photons. This has to be factored in, besides manufacturer supplied source percent uncertainity, and exponential law derating of the activity of the sample, using the supplied date of manufacture, and the Cs137 half-life of 30.05 years.<\/p>\n\n\n\n<p>Beta- radiation has a high linear attenuation coefficient in air, and would skew the measurements when the jig is very close to the tube through their contribution in the final measure. A standard food grade aluminium foil is sufficient to filter them out to a negligible level, while leaving almost all gamma ray photons unscathed. Nevertheless we have factored in attenuation from air and aluminium through air and  aluminium for both Beta- and gamma based on litterature and NIST database data.<\/p>\n\n\n\n<p>The source is then placed on a jig powered by a linear actuator, so that it moves freely inside the channel along the x axis. the center of the point source disc should be on the x axis and intercept the center of mass of the GM tube. The x axis should be perpendicular to the point source disc and GM tube.<\/p>\n\n\n\n<p>The raspberry Pi platforms registers pulse and operates the linear actuator. A model with position feedback is required for accurate jig position determination, after manual position calibration, or alternatively, a time of flight (TOF) \/ LIDAR sensor module should be used. This solution should also be subjected to calibration beforehand.<\/p>\n\n\n\n<p>The GM calibration helper for a Cs-137 point source Python script is in alpha stage of development but the bulk of the work is done.<\/p>\n\n\n\n<p>The workflow of the script starts with the following parameter inputs :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Point source activity, supplied in either Bq or Ci units.<\/li>\n\n\n\n<li>The activity_unit enumeration is used to set up the unit of activity<\/li>\n\n\n\n<li>The radioisotope used is hard-coded to Cs137, and it&#8217;s decay scheme is factored in to take into account only Gamma activity.<\/li>\n\n\n\n<li>Decay % that give rise to gamma photons<\/li>\n\n\n\n<li>Cs137 half-life as a constant<\/li>\n\n\n\n<li>Source date of manufacture<\/li>\n\n\n\n<li>Aluminium mass extinction coefficients for Beta and gamma radiation (using Cs137 decay energies)<\/li>\n\n\n\n<li>Air mass extinction coefficients for Beta and gamma radiation (using Cs137 decay energies)<\/li>\n\n\n\n<li>Distance range (min,max) of the source relative to the GM tube center of mass on the jig y-axis<\/li>\n\n\n\n<li>GM Tube geometry : length and diameter.<\/li>\n\n\n\n<li>GM tube intrinsic dead time estimation (or from datasheet)<\/li>\n\n\n\n<li>GM tube efficiency estimation (or from datasheet)<\/li>\n<\/ul>\n\n\n\n<p>On that basis, we will first calculate the mean path length from the point source to the tube as a function of y axis distance. For this we will use basic trigonometry and integrate over the tube length, all the ray paths from the source. This mean path length will be used to factor in the linear attenuation coefficient of air for gamma radiation at 0.611 MeV energy. Beta radiation is assumed to be filtered up to an insignificant amount, but we can still calculate the attenuation based on aluminium mass extinction coefficient and foil thickness to check for filtering efficiency of beta radiation.<\/p>\n\n\n\n<p>The compound attenuation of air plus aluminium filter is calculated for the gamma radiation.<\/p>\n\n\n\n<p>The radiant flux from the point source received by the GM tube is then calculated. The standard law<\/p>\n\n\n\n<p>$$ Flux =\\frac{P}{4 \\pi r^{2}} $$<\/p>\n\n\n\n<p>assumes a spherical irradiated surface. since the cross section of the GM Tube is a plane, and taking into account that $$ GMtubewidth \\ll GMtubelength $$, we will perform a single integration along the tube cylinder axis to get the corrected number of photons $$ R_{net} $$ crossing the tube section, instead of a double integration.<\/p>\n\n\n\n<p>$$ R_{totvac} \\simeq 2\\times\\int_{0}^{\\frac{GMtubelength}{2}}\\frac{P_{net}}{4 \\pi (x^2 + r^2)} cos(arctan(\\frac{x}{r}))dx \\hspace{2mm} \\times GMtubewidth $$<\/p>\n\n\n\n<p>Which simplifies to :<\/p>\n\n\n\n<p>$$ R_{totvac} \\simeq 2\\times\\frac{P_{net}\\frac{GMtubelength}{2}}{4\\pi r \\sqrt{(\\frac{GMtubelength}{2})^{2} + r^{2}}} \\times GMtubewidth $$<\/p>\n\n\n\n<p>Also,<\/p>\n\n\n\n<p>$$ P_{net} $$ is the gamma source activity. It has to take into account the percent of decays giving rise to gamma photons, and the reduction of activity since the source date of manufacture.<\/p>\n\n\n\n<p>$$ P_{net} = 0.851 P_{nom} e^{-\\frac{ln(2)}{t_{1\/2}} (t_{1} &#8211; t_{0})} $$<\/p>\n\n\n\n<p>$$ t_{1} $$ is the time of the calibration<\/p>\n\n\n\n<p>$$ t_{0} $$ is the time of source manufacture. <\/p>\n\n\n\n<p>and, accounting for attenuation :<\/p>\n\n\n\n<p>$$ R_{tot} \\simeq 2\\times att_{\\gamma}\\frac{P_{net}\\frac{GMtubelength}{2}}{4\\pi r \\sqrt{(\\frac{GMtubelength}{2})^{2} + r^{2}}} \\times GMtubewidth $$<\/p>\n\n\n\n<p>To calculate the air attenuation of the gamma photons, we will use an approximation that has an expression in terms of elementary functions.<\/p>\n\n\n\n<p>A gamma photon path length &#8216;l&#8217; from the point source to any point on the x axis (axis of the GM tube represented as a cylinder) can be approximated as the length of the hypotenuse (neglecting paths that strike the cylinder off axis) :<\/p>\n\n\n\n<p>$$ l = \\sqrt{x^{2} + r^{2}} $$<\/p>\n\n\n\n<p>The average path length is :<\/p>\n\n\n\n<p>$$ l_{avg} = {\\frac{2}{GM tube length}} \\int_{0}^{\\frac{GM tube length}{2}} \\sqrt{x^2 + r^2}dx $$<\/p>\n\n\n\n<p>Which yields the following expression :<\/p>\n\n\n\n<p>$$ l_{avg} = \\frac{{r^{2} \\operatorname{arsinh}\\left(\\frac{GMtubelength}{2r}\\right)}}{GMtubelength} + \\frac{\\sqrt{({\\frac{GMtubelength}{2}})^{2} + r^{2}}}{2} $$<\/p>\n\n\n\n<p>The attenuation factor applied to the flux :<\/p>\n\n\n\n<p>$$ att_{\\gamma}\\simeq e^{-\\mu_{air} l_{avg} -\\mu_{Al}w} $$<\/p>\n\n\n\n<p>$$ w $$ being the Aluminium foil thickness<\/p>\n\n\n\n<p>$$ \\mu_{air} $$ being the linear attenuation coefficient of air at 0.661 MeV gamma energy.<\/p>\n\n\n\n<p>$$ \\mu_{Al} $$ being the linear attenuation coefficient of Aluminium at 0.661 MeV gamma energy.<\/p>\n\n\n\n<p>A small fraction of these photons will trigger an ionization of the GM_tube gas medium. These will form the measured tube event count per second. $$ R_{net} $$ At low count rates, dead time effects are negligible, and provided sufficiently long measurement times, the tube efficiency alpha can be determined :<\/p>\n\n\n\n<p>$$ \\alpha = \\frac{R_{net}} {R_{tot}} $$<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Resources<\/h2>\n\n\n\n<p>Note : For up to date code, please check <a href=\"https:\/\/www.github.com\/rodv92\/GMobile\" class=\"ek-link\">https:\/\/www.github.com\/rodv92\/GMobile<\/a><\/p>\n\n\n\n<p>This is the calibration helper Python script draft.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><textarea class=\"code-block-pro-copy-button-textarea\" aria-hidden=\"true\" readonly>import scipy as sp\nimport math as m\nimport numpy as np\nimport time as time\nfrom datetime import datetime\nimport matplotlib.pyplot as plt\nfrom enum import Enum\n\n\n# using S.I units (unless specified otherwise in comment immediately following \n# declaration)\n\nclass activity_unit(Enum):\n    BQ = 1 #Bq\n    CI = 2 #Ci\n\nactivity_unit = Enum(&#8216;activity_unit&#8217;, [&#8216;BQ&#8217;,&#8217;CI&#8217;])\n\n\n\n# assuming a Cs-137 source, and a collimator made of thick lead of the same width as the GM tube and the same height as the tube, with the point source at the e# ntrance of the channel\n\n\nP_nom = 370e-3 # source activity (unit determined by used_activity_unit)\nused_activity_unit = activity_unit.BQ\n# it&#8217;s better to use a high activity source in order to drive the count at very high levels for dead-time effects to be come noticeable\n# the lower the analog frontend dead-time that results in reliable A\/D conversion, the higher the activity of the source is required.\n\n\ngamma_yield = 0.851 # ratio of decays that give rise to gamma photons\n\nsource_date_of_manufacture = &#8220;2022-12-01T19:00:00Z&#8221;\ndt_source_dom = datetime.fromisoformat(source_date_of_manufacture)\ndt_now = datetime.now()\nsource_age = (dt_now &#8211; dt_source_dom).total_seconds()\nhalf_life = 30.05 # Cs137 half-life in years\nhalf_life = half_life*365*24*60*60 # Cs137 half-life converted to seconds \n\n\u00b51 = 0.000103 # linear attenuation coefficient of air for the gamma energy of 667 kEv &#8211; emmited by Ba137m\n#\u00b52 = 0.1 # linear attenuation coefficient of beta shield for the gamma energy of 667 kEv. We assume that the beta shield filters beta particles to a negligible amount. \nAl_filter_thickness = 0.001 # cm  0.001 cm = 10\u00b5m standard food grade aluminium foil thickness\n\n\nmax_distance = 0.3\ndistance = 0.15 # distance from point source to center of detector. (meters)\nmin_distance = 0.05\n# GM tube axis is normal to line from point source to GM tube center.\n\nGM_tube_length = 0.075 # glass envelope length only (meters)\nGM_tube_diameter = 0.01 # glass envelope diameter (meters)\nGM_tube_alpha = 0.0319 # tube efficiency &#8211; not all incoming photons trigger an ionization event.\nalpha = GM_tube_alpha\n\nGM_tube_detection_cross_section_area = GM_tube_length*GM_tube_diameter\nGMT_dcsa = GM_tube_detection_cross_section_area # variable alias\n\nGM_tube_dead_time = 80e-6 # tube intrinsic (charge drift time) dead time\nGMT_det = GM_tube_dead_time\n\nif (used_activity_unit == activity_unit.BQ):\n    pass\nelif (used_activity_unit == activity_unit.CI):\n    P_nom *= 3.7e10 # convert to Bq\n\n\n#derate activity based on % decay gamma yield and source age.\nP_net = gamma_yield*P_nom*exp(-(m.log(2)\/half_life)*source_age)\n\n#calculate mean path length of gamma photons reaching the tube.\nmean_path = (1\/2)*(distance**2 + (GM_tube_length\/2)**2)**(1\/2) + (distance**2)*m.arcsinh*(GM_tube_length\/(2*distance))\/GM_tube_length\n#calculate attenuation from linear attenuation coefficient\ngamma_att_air = m.exp(-\u00b51*mean_path)\n\n\nAl_density = 2.7 # g\/cm3\n#Al_mass_att_beta_cs137 = 15.1 #cm2\/mg\nAl_mass_att_beta_cs137 = 15.1e3 #cm2\/g beta+\/- attenuation for Cs137 emitter https:\/\/doi.org\/10.1016\/j.anucene.2013.07.023\n# not used in subsequent calibration formulas, assuming that beta is filtered to an insignificant amount. standard food grade aluminium foil of 10\u00b5m thickness gives an attenuation factor in the order of 1e-18\n\n\u00b52 = Al_mass_att_beta_cs137*Al_density #cm-1\nbeta_att_Al = m.exp(-Al_filter_thickness*\u00b52)\n# To check the effectiveness of beta filtering.\n# not used in subsequent calibration formulas, assuming that beta is filtered to an insignificant amount. standard food grade aluminium foil of 10\u00b5m thickness gives an attenuation factor in the order of 1e-18\n\nAl_mass_att_gamma_Ba137m = 7.484e-2 #cm2\/g gamma attenuation for Aluminium at 667 kEv\n\u00b53 = Al_mass_att_gamma_Ba137m*Al_density\n\ngamma_att_Al = m.exp(-Al_filter_thickness*\u00b53)\n\n#calculate total gamma attenuation from air and Al filter.\n\ngamma_att_total = gamma_att_air*gamma_att_Al\n\n\n\n\nimport GMobile as GM\n\n\n# CALIBRATION step 0\n\n# Estimates the analog front end dead-time by timing the pulse width while the GM Tube is exposed to background radiation\n\nbackground_measure_pulsewidth_total_pulses = 60 # time to spend in seconds measuring pulse width\nbackground_measure_pulsewidth_max_fails = 20 # time to spend in seconds measuring pulse width\nrise_timeout_ms = 20000\nfall_timeout_ms = 20\n\n\n(pulsewidth,stdev) = GM.measurePulseWidth(background_measure_pulsewidth_total_pulses,background_measure_pulsewidth_max_fails,rise_timeout_ms,fall_timeout_ms)\n\n\n# CALIBRATION step 1\n\n#Measure the background CPM with the collimating assembly, but the source removed and far away.\n# call main.py and average CPM over specified background_acquire_time in seconds\n\n\nbackground_acquire_time = 600 # time to spend in seconds acquiring background radiation levels after first 60 sec of acquisition.\n\n\nchars = None\nchars = input(&#8220;Step 1 &#8211; acquiring background radiation cpm during &#8221; + background_acquire_time + &#8221; seconds. Please put the source as far away as possible. press ENTER to start&#8221;)\nwhile chars is None:\n    chars = input(&#8220;Step 1 &#8211; acquiring background radiation cpm during &#8221; + background_acquire_time + &#8221; seconds. Please put the source as far away as possible. press ENTER to start&#8221;)\n    \n\nGM.SetupGPIOEventDetect() # sets up the GPIO event callback\n\ns = 0\ncpm_sum = 0\nwhile (s &lt; background_acquire_time):\n    cpm = GM.process_events(False,False) # This call should take exactly one second.\n    if (cpm != -1):\n        cpm_sum += cpm\n        s += 1\n\ncpm_background = cpm_sum\/background_acquire_time\n\ndef model1_estimated_GM_CPM(true_count,t1,t2): # Muller&#8217;s serial t1 paralyzable dead time followed by t2 non paralyzable dead time model\n    alpha = t1\/t2\n    x = true_count*t2\n    corrected_cpm_1 = true_count\/((1-alpha)*x + m.exp(alpha*x))\n    return corrected_cpm_1\n\ndef model2_estimated_GM_CPM(true_count,t1):\n    corrected_cpm_2 = true_count*m.exp(-true_count*t1)\n    return corrected_cpm_2\n\ndef model3_estimated_GM_CPM(true_count,t2):\n    corrected_cpm_3 = true_count\/(1+true_count*t2)\n    return corrected_cpm_3\n\n\ndef movejig(position):\n\n    #TODO : linear actuator positioning code\n    err = 0\n    \n    return err #  err = 0 : actuation OK\n\ndef efficiency_step(distance=0.15,movestep=0.005,efficiency_placing_time=600,efficiency_stab_time=60,last_secs_stab_time=60,min_cpm_efficiency_cal=8*cpm_background,max_cpm_efficiency_cal=16*cpm_background):\n\n    # CALIBRATION step 2\n\n    print(&#8220;Step 2 : automated GM tube efficiency calculation&#8221;)\n        \n    s = 0\n    s_stab = 0\n    cpm_stab = []\n    while (s &lt; efficiency_placing_time):\n        #print(&#8220;Step 2.1 &#8211; efficiency computation: you have &#8221; + efficiency_placing_time + &#8220;seconds to put the source at a distance to obtain a reading between &#8221; + min_cpm_efficiency_cal + &#8221; and &#8221; + max_cpm_efficiency_cal + &#8221; cpm. press ENTER when in range&#8221;)\n        #print(&#8220;the timer will start counting down after the first 60 seconds have elapsed &#8211; it will then exit the step if cpm is stabilized in range for a whole &#8221; + efficiency_stab_time + &#8221; secs, and get the cpm average for the last &#8221; + last_secs_stab_time + &#8221; secs. Do not move the source during that time&#8221;)\n        cpm = GM.process_events(False,False) # This call should take exactly one second.\n        if (cpm != -1): # first 60 seconds have elapsed.\n            cpm_sum += cpm\n            s += 1\n            if(cpm > min_cpm_efficiency_cal and cpm &lt; max_cpm_efficiency_cal): # in range.\n                s_stab += 1\n                cpm_stab.append(cpm)\n            elif(cpm > max_cpm_efficiency_cal): # out of range high. reset stabilized countrate time counter\n                distance += movestep\n                movejig(distance)\n                s_stab = 0\n                cpm_stab = []\n            elif(cpm &lt; min_cpm_efficiency_cal): # out of range high. reset stabilized countrate time counter\n                distance -= movestep\n                movejig(distance)\n                s_stab = 0\n                cpm_stab = []\n                \n            \n            print(&#8220;cpm:\\t&#8221; + cpm)\n            print(&#8220;stabilized_time:\\t&#8221; + s_stab)\n            print(&#8220;distance:\\t&#8221; + distance)\n            \n            \n            if s_stab >= efficiency_stab_time:\n                #distance = input(&#8220;Please input distance in meters from GM_tube to source at stabilized reading&#8221;)\n                cpm_stab = cpm_stab[-last_secs_stab_time:]\n                cpm_stab_avg = sum(cpm_stab)\/last_secs_stab_time\n                break\n\n    cpm_efficiency_calc = cpm_stab_avg &#8211; cpm_background\n\n    #calculate mean path length of gamma photons reaching the tube.\n    mean_path = (1\/2)*(distance**2 + (GM_tube_length\/2)**2)**(1\/2) + (distance**2)*m.arcsinh*(GM_tube_length\/(2*distance))\/GM_tube_length\n    #calculate attenuation from linear attenuation coefficient\n    gamma_att_air = m.exp(-\u00b51*mean_path)\n\n    #calculate total gamma attenuation from air and Al filter.\n    gamma_att_total = gamma_att_air*gamma_att_Al\n\n\n    flux = gamma_att_total*2*GM_tube_width*(P_net*(GM_tube_length\/2))\/(4*m.pi*distance*((GM_tubelength\/2)**2 + distance**2)**(1\/2))\n# gamma flux in photons.s^-1 crossing the GM tube.  Accounting for planar cross section of GM Tube (instead of solid angle) and attenuation from air and beta filter of gamma photons.\n    theoretical_cpm = 60*flux # assuming GM tube efficiency of 1, All photons would give rise to ionization events inside the GM tube\n\n    if(s != efficiency_placing_time):\n        efficiency = cpm_efficiency_calc\/theoretical_cpm\n        print(&#8220;computed efficiency:\\t&#8221; + efficiency)\n        return((efficiency,distance))\n    else:\n        print(&#8220;efficiency calibration failed.&#8221;)\n        return((-1,distance))\n\n# Compute efficiency of detection at a count rate sufficiently high enough above background but not as high as dead time effects become significant.\nefficiency_placing_time = 600\nefficiency_stab_time = 180\nlast_secs_stab_time = 60\nmin_cpm_efficiency_cal = 8*cpm_background\nmax_cpm_efficiency_cal = 16*cpm_background\n\n\nchars = None\nchars = input(&#8220;Step 2.0 &#8211; efficiency computation: please put the source at &#8221; + distance + &#8220;cm from the GM tube, normal to the tube, withint the collimator. press ENTER to start&#8221;)\n\nmovejig(distance) # initial position\n(efficiency,distance) = efficiency_step(distance) # gets efficiency, -1 if failed, and jig to source distance\n\nwhile (efficiency == -1):\n    print(&#8220;efficiency calculation step failed. repeating&#8221;)\n    (efficiency,distance) = efficiency_step(distance)\n\n\n#STEP 3 : record countrate while stepping the source jig towards the GM tube\nstep3_wait_time = 120\nstep3_last_seconds_measure = 60\nstep3_last_seconds_measure = min(120,step3_last_seconds_measure) # ensure the total seconds we sample is lower than step3_wait_time\nx_distance = np.arange(max_distance,min_distance,-0.005)\n\ny_cpm_m = np.empty(len(x_distance)) # array of average of count rate for each measurement sampling\ny_cpm_m[:] = np.nan\n\ny_std_m = np.empty(len(x_distance)) # array of standard deviation of count rate for each measurement sampling\ny_std_m[:] = np.nan\n\ny_cpm_t = np.empty(len(x_distance)) # array of theoretical cpms derated with GM tube efficiency\ny_cpm_t[:] = np.nan\n\ny_cpm_tm = np.empty(len(x_distance)) # array of theoretical cpms derated with GM tube efficiency and dead time effects\ny_cpm_tm[:] = np.nan\n\n\ndistance_cpm_avg_m = np.stack([x_distance,y_cpm_m],axis=1) # tabular data for cpm (average) as a function of source\/GM tube distance\ndistance_cpm_std_m =  np.stack([x_distance,y_std_m],axis=1) # tabular data for cpm (std dev) as a function of source\/GM tube distance\n\ndistance_cpm_t = np.stack([x_distance,y_cpm_t],axis=1) # tabular data for cpm (theoretical), derated by GM tube efficiency as a function of distance\ndistance_cpm_tm = np.stack([x_distance,y_cpm_tm],axis=1) # tabular data for cpm (theoretical), derated by GM tube efficiency and accounting for dead time effects\n\n\ndistance = max_distance # retract actuator to minimum to get longest source to GM tube distance.\nif not (movejig(distance)): # no actuation error\n    idx = 0\n    while(distance > min_distance):\n        if(movejig(distance)):\n            break # actuation error, break loop\n        distance -= 0.05\n        cpm_stab = [] \n        #TODO : reset deque() in GMobile after jig move, to get rid of the inertia induced by the sliding window sampling\n        while(s &lt; step3_wait_time):\n            if(s >= (step3_wait_time &#8211; step3_last_seconds_measure)):\n                cpm_stab.append(GM.process_events(False,False)) # This call should take exactly one second.\n            else:\n                time.sleep(1)\n        cpm_avg = np.average(cpm_stab)\n        cpm_std = np.std(cpm_stab)\n        distance_cpm_avg_m[idx][1] = cpm_avg\n        distance_cpm_std_m[idx][1] = cpm_std\n        \n        \n        #calculate mean path length of gamma photons reaching the tube.\n        mean_path = (1\/2)*(distance**2 + (GM_tube_length\/2)**2)**(1\/2) + (distance**2)*m.arcsinh*(GM_tube_length\/(2*distance))\/GM_tube_length\n        #calculate attenuation from linear attenuation coefficient\n        gamma_att_air = m.exp(-\u00b51*mean_path)\n        #calculate total gamma attenuation from air and Al filter.\n        gamma_att_total = gamma_att_air*gamma_att_Al\n\n        flux = gamma_att_total*2*GM_tube_width*(P_net*(GM_tube_length\/2))\/(4*m.pi*distance*((GM_tubelength\/2)**2 + distance**2)**(1\/2))\n\n        # gamma flux in photons.s^-1 crossing the GM tube. Accounting for planar cross section of GM Tube (instead of solid angle) and attenuation from air and beta filter of gamma photons.\n        theoretical_cpm_eff = 60*flux*efficiency # theoretical cpm (derated with GM tube efficiency estimated in step 2.0)\n\n        distance_cpm_t[idx][1] = theoretical_cpm_eff\n        distance_cpm_tm[idx][1] = model1_estimated_GM_CPM(theoretical_cpm_eff) # theoretical cpm from above with dead time compensation\n\n\n\n\ndef compare_cpm_measured_theoretical(theoretical,measured):\n\n    devsum = 0\n    devratiosum = 0\n\n    if (len(theoretical) != len(measured)):\n        return (-1,-1)\n    \n    for idx in range(0,len(theoretical)):\n\n        devratiosum += abs((measured[idx][1] &#8211; theoretical[idx][1])\/measured[idx][1])\n        devsum = (measured[idx][1] &#8211; theoretical[idx][1])**2\n\n    mape = devratiosum\/len(theoretical)\n    return (devsum,mape)\n\ndef plotcurves(curve_x, curve_y1, curve_y2, color_curve_1, color_curve_2, label_curve_1, label_curve_2):\n    \n\n    plt.plot(curve_x, curve_y1, color_curve_1, label=label_curve_1)\n    plt.plot(curve_x, curve_y2, color_curve_2, label=label_curve_2)\n\n    plt.xlabel(&#8216;distance (m)&#8217;)\n    plt.ylabel(&#8216;count rate (cpm)&#8217;)\n    plt.legend()\n    plt.grid()\n    plt.show()\n\nprint(compare_cpm_measured_theoretical(distance_cpm_tm,distance_cpm_avg_m))\nplotcurves(distance_cpm_t[:,0],distance_cpm_avg_m[:,1],distance_cpm_tm[:,1],&#8217;r-&#8216;, &#8216;g-&#8216;, &#8220;measured&#8221;,&#8221;theoretical_compensated&#8221;)\n<\/textarea><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #81A1C1\">import<\/span><span style=\"color: #D8DEE9FF\"> scipy <\/span><span style=\"color: #81A1C1\">as<\/span><span style=\"color: #D8DEE9FF\"> sp<\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">import<\/span><span style=\"color: #D8DEE9FF\"> math <\/span><span style=\"color: #81A1C1\">as<\/span><span style=\"color: #D8DEE9FF\"> m<\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">import<\/span><span style=\"color: #D8DEE9FF\"> numpy <\/span><span style=\"color: #81A1C1\">as<\/span><span style=\"color: #D8DEE9FF\"> np<\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">import<\/span><span style=\"color: #D8DEE9FF\"> time <\/span><span style=\"color: #81A1C1\">as<\/span><span style=\"color: #D8DEE9FF\"> time<\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">from<\/span><span style=\"color: #D8DEE9FF\"> datetime <\/span><span style=\"color: #81A1C1\">import<\/span><span style=\"color: #D8DEE9FF\"> datetime<\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">import<\/span><span style=\"color: #D8DEE9FF\"> matplotlib<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9FF\">pyplot <\/span><span style=\"color: #81A1C1\">as<\/span><span style=\"color: #D8DEE9FF\"> plt<\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">from<\/span><span style=\"color: #D8DEE9FF\"> enum <\/span><span style=\"color: #81A1C1\">import<\/span><span style=\"color: #D8DEE9FF\"> Enum<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #616E88\"># using S.I units (unless specified otherwise in comment immediately following <\/span><\/span>\n<span class=\"line\"><span style=\"color: #616E88\"># declaration)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">class<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #8FBCBB\">activity_unit<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #8FBCBB; font-weight: bold\">Enum<\/span><span style=\"color: #ECEFF4\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    BQ <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\">#Bq<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    CI <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\">#Ci<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">activity_unit <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">Enum<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #A3BE8C\">activity_unit<\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">[<\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #A3BE8C\">BQ<\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #A3BE8C\">CI<\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #ECEFF4\">])<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #616E88\"># assuming a Cs-137 source, and a collimator made of thick lead of the same width as the GM tube and the same height as the tube, with the point source at the e# ntrance of the channel<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">P_nom <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">370e-3<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># source activity (unit determined by used_activity_unit)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">used_activity_unit <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> activity_unit<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9FF\">BQ<\/span><\/span>\n<span class=\"line\"><span style=\"color: #616E88\"># it&#39;s better to use a high activity source in order to drive the count at very high levels for dead-time effects to be come noticeable<\/span><\/span>\n<span class=\"line\"><span style=\"color: #616E88\"># the lower the analog frontend dead-time that results in reliable A\/D conversion, the higher the activity of the source is required.<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">gamma_yield <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0.851<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># ratio of decays that give rise to gamma photons<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">source_date_of_manufacture <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">2022-12-01T19:00:00Z<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">dt_source_dom <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> datetime<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">fromisoformat<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">source_date_of_manufacture<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">dt_now <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> datetime<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">now<\/span><span style=\"color: #ECEFF4\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">source_age <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">dt_now <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\"> dt_source_dom<\/span><span style=\"color: #ECEFF4\">).<\/span><span style=\"color: #88C0D0\">total_seconds<\/span><span style=\"color: #ECEFF4\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">half_life <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">30.05<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># Cs137 half-life in years<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">half_life <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> half_life<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #B48EAD\">365<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #B48EAD\">24<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #B48EAD\">60<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #B48EAD\">60<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># Cs137 half-life converted to seconds <\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">\u00b51 <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0.000103<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># linear attenuation coefficient of air for the gamma energy of 667 kEv - emmited by Ba137m<\/span><\/span>\n<span class=\"line\"><span style=\"color: #616E88\">#\u00b52 = 0.1 # linear attenuation coefficient of beta shield for the gamma energy of 667 kEv. We assume that the beta shield filters beta particles to a negligible amount. <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">Al_filter_thickness <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0.001<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># cm  0.001 cm = 10\u00b5m standard food grade aluminium foil thickness<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">max_distance <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0.3<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">distance <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0.15<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># distance from point source to center of detector. (meters)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">min_distance <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0.05<\/span><\/span>\n<span class=\"line\"><span style=\"color: #616E88\"># GM tube axis is normal to line from point source to GM tube center.<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">GM_tube_length <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0.075<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># glass envelope length only (meters)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">GM_tube_diameter <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0.01<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># glass envelope diameter (meters)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">GM_tube_alpha <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0.0319<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># tube efficiency - not all incoming photons trigger an ionization event.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">alpha <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> GM_tube_alpha<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">GM_tube_detection_cross_section_area <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> GM_tube_length<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\">GM_tube_diameter<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">GMT_dcsa <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> GM_tube_detection_cross_section_area <\/span><span style=\"color: #616E88\"># variable alias<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">GM_tube_dead_time <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">80e-6<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># tube intrinsic (charge drift time) dead time<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">GMT_det <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> GM_tube_dead_time<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">used_activity_unit <\/span><span style=\"color: #81A1C1\">==<\/span><span style=\"color: #D8DEE9FF\"> activity_unit<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9FF\">BQ<\/span><span style=\"color: #ECEFF4\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">pass<\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">elif<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">used_activity_unit <\/span><span style=\"color: #81A1C1\">==<\/span><span style=\"color: #D8DEE9FF\"> activity_unit<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9FF\">CI<\/span><span style=\"color: #ECEFF4\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    P_nom <\/span><span style=\"color: #81A1C1\">*=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">3.7e10<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># convert to Bq<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #616E88\">#derate activity based on % decay gamma yield and source age.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">P_net <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> gamma_yield<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\">P_nom<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #88C0D0\">exp<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">m<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">log<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #D8DEE9FF\">half_life<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\">source_age<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #616E88\">#calculate mean path length of gamma photons reaching the tube.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">mean_path <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">distance<\/span><span style=\"color: #81A1C1\">**<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">GM_tube_length<\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #81A1C1\">**<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #81A1C1\">**<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">distance<\/span><span style=\"color: #81A1C1\">**<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\">m<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9FF\">arcsinh<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">GM_tube_length<\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\">distance<\/span><span style=\"color: #ECEFF4\">))<\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #D8DEE9FF\">GM_tube_length<\/span><\/span>\n<span class=\"line\"><span style=\"color: #616E88\">#calculate attenuation from linear attenuation coefficient<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">gamma_att_air <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> m<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">exp<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\">\u00b51<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\">mean_path<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">Al_density <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">2.7<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># g\/cm3<\/span><\/span>\n<span class=\"line\"><span style=\"color: #616E88\">#Al_mass_att_beta_cs137 = 15.1 #cm2\/mg<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">Al_mass_att_beta_cs137 <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">15.1e3<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\">#cm2\/g beta+\/- attenuation for Cs137 emitter https:\/\/doi.org\/10.1016\/j.anucene.2013.07.023<\/span><\/span>\n<span class=\"line\"><span style=\"color: #616E88\"># not used in subsequent calibration formulas, assuming that beta is filtered to an insignificant amount. standard food grade aluminium foil of 10\u00b5m thickness gives an attenuation factor in the order of 1e-18<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">\u00b52 <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> Al_mass_att_beta_cs137<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\">Al_density <\/span><span style=\"color: #616E88\">#cm-1<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">beta_att_Al <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> m<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">exp<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\">Al_filter_thickness<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\">\u00b52<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #616E88\"># To check the effectiveness of beta filtering.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #616E88\"># not used in subsequent calibration formulas, assuming that beta is filtered to an insignificant amount. standard food grade aluminium foil of 10\u00b5m thickness gives an attenuation factor in the order of 1e-18<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">Al_mass_att_gamma_Ba137m <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">7.484e-2<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\">#cm2\/g gamma attenuation for Aluminium at 667 kEv<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">\u00b53 <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> Al_mass_att_gamma_Ba137m<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\">Al_density<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">gamma_att_Al <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> m<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">exp<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\">Al_filter_thickness<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\">\u00b53<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #616E88\">#calculate total gamma attenuation from air and Al filter.<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">gamma_att_total <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> gamma_att_air<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\">gamma_att_Al<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">import<\/span><span style=\"color: #D8DEE9FF\"> GMobile <\/span><span style=\"color: #81A1C1\">as<\/span><span style=\"color: #D8DEE9FF\"> GM<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #616E88\"># CALIBRATION step 0<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #616E88\"># Estimates the analog front end dead-time by timing the pulse width while the GM Tube is exposed to background radiation<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">background_measure_pulsewidth_total_pulses <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">60<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># time to spend in seconds measuring pulse width<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">background_measure_pulsewidth_max_fails <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">20<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># time to spend in seconds measuring pulse width<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">rise_timeout_ms <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">20000<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">fall_timeout_ms <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">20<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">pulsewidth<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\">stdev<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> GM<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">measurePulseWidth<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">background_measure_pulsewidth_total_pulses<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\">background_measure_pulsewidth_max_fails<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\">rise_timeout_ms<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\">fall_timeout_ms<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #616E88\"># CALIBRATION step 1<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #616E88\">#Measure the background CPM with the collimating assembly, but the source removed and far away.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #616E88\"># call main.py and average CPM over specified background_acquire_time in seconds<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">background_acquire_time <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">600<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># time to spend in seconds acquiring background radiation levels after first 60 sec of acquisition.<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">chars <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">None<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">chars <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">input<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">Step 1 - acquiring background radiation cpm during <\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> background_acquire_time <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\"> seconds. Please put the source as far away as possible. press ENTER to start<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">while<\/span><span style=\"color: #D8DEE9FF\"> chars <\/span><span style=\"color: #81A1C1\">is<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">None<\/span><span style=\"color: #ECEFF4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    chars <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">input<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">Step 1 - acquiring background radiation cpm during <\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> background_acquire_time <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\"> seconds. Please put the source as far away as possible. press ENTER to start<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">GM<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">SetupGPIOEventDetect<\/span><span style=\"color: #ECEFF4\">()<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># sets up the GPIO event callback<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">s <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">cpm_sum <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0<\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">while<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">s <\/span><span style=\"color: #81A1C1\">&lt;<\/span><span style=\"color: #D8DEE9FF\"> background_acquire_time<\/span><span style=\"color: #ECEFF4\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    cpm <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> GM<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">process_events<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #81A1C1\">False<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #81A1C1\">False<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># This call should take exactly one second.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">cpm <\/span><span style=\"color: #81A1C1\">!=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #ECEFF4\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        cpm_sum <\/span><span style=\"color: #81A1C1\">+=<\/span><span style=\"color: #D8DEE9FF\"> cpm<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        s <\/span><span style=\"color: #81A1C1\">+=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">1<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">cpm_background <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> cpm_sum<\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #D8DEE9FF\">background_acquire_time<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">def<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">model1_estimated_GM_CPM<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9\">true_count<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9\">t1<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9\">t2<\/span><span style=\"color: #ECEFF4\">):<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># Muller&#39;s serial t1 paralyzable dead time followed by t2 non paralyzable dead time model<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    alpha <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> t1<\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #D8DEE9FF\">t2<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    x <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> true_count<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\">t2<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    corrected_cpm_1 <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> true_count<\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #ECEFF4\">((<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\">alpha<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\">x <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> m<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">exp<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">alpha<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\">x<\/span><span style=\"color: #ECEFF4\">))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">return<\/span><span style=\"color: #D8DEE9FF\"> corrected_cpm_1<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">def<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">model2_estimated_GM_CPM<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9\">true_count<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9\">t1<\/span><span style=\"color: #ECEFF4\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    corrected_cpm_2 <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> true_count<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\">m<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">exp<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\">true_count<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\">t1<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">return<\/span><span style=\"color: #D8DEE9FF\"> corrected_cpm_2<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">def<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">model3_estimated_GM_CPM<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9\">true_count<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9\">t2<\/span><span style=\"color: #ECEFF4\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    corrected_cpm_3 <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> true_count<\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\">true_count<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\">t2<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">return<\/span><span style=\"color: #D8DEE9FF\"> corrected_cpm_3<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">def<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">movejig<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9\">position<\/span><span style=\"color: #ECEFF4\">):<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #616E88\">#<\/span><span style=\"color: #81A1C1\">TODO<\/span><span style=\"color: #616E88\"> : linear actuator positioning code<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    err <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">return<\/span><span style=\"color: #D8DEE9FF\"> err <\/span><span style=\"color: #616E88\">#  err = 0 : actuation OK<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">def<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">efficiency_step<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9\">distance<\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #B48EAD\">0.15<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9\">movestep<\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #B48EAD\">0.005<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9\">efficiency_placing_time<\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #B48EAD\">600<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9\">efficiency_stab_time<\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #B48EAD\">60<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9\">last_secs_stab_time<\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #B48EAD\">60<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9\">min_cpm_efficiency_cal<\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #B48EAD\">8<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\">cpm_background<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9\">max_cpm_efficiency_cal<\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #B48EAD\">16<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\">cpm_background<\/span><span style=\"color: #ECEFF4\">):<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #616E88\"># CALIBRATION step 2<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #88C0D0\">print<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">Step 2 : automated GM tube efficiency calculation<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    s <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    s_stab <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    cpm_stab <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">[]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">while<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">s <\/span><span style=\"color: #81A1C1\">&lt;<\/span><span style=\"color: #D8DEE9FF\"> efficiency_placing_time<\/span><span style=\"color: #ECEFF4\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #616E88\">#print(&quot;Step 2.1 - efficiency computation: you have &quot; + efficiency_placing_time + &quot;seconds to put the source at a distance to obtain a reading between &quot; + min_cpm_efficiency_cal + &quot; and &quot; + max_cpm_efficiency_cal + &quot; cpm. press ENTER when in range&quot;)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #616E88\">#print(&quot;the timer will start counting down after the first 60 seconds have elapsed - it will then exit the step if cpm is stabilized in range for a whole &quot; + efficiency_stab_time + &quot; secs, and get the cpm average for the last &quot; + last_secs_stab_time + &quot; secs. Do not move the source during that time&quot;)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        cpm <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> GM<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">process_events<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #81A1C1\">False<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #81A1C1\">False<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># This call should take exactly one second.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">cpm <\/span><span style=\"color: #81A1C1\">!=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #ECEFF4\">):<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># first 60 seconds have elapsed.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            cpm_sum <\/span><span style=\"color: #81A1C1\">+=<\/span><span style=\"color: #D8DEE9FF\"> cpm<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            s <\/span><span style=\"color: #81A1C1\">+=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">1<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">cpm <\/span><span style=\"color: #81A1C1\">&gt;<\/span><span style=\"color: #D8DEE9FF\"> min_cpm_efficiency_cal <\/span><span style=\"color: #81A1C1\">and<\/span><span style=\"color: #D8DEE9FF\"> cpm <\/span><span style=\"color: #81A1C1\">&lt;<\/span><span style=\"color: #D8DEE9FF\"> max_cpm_efficiency_cal<\/span><span style=\"color: #ECEFF4\">):<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># in range.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">                s_stab <\/span><span style=\"color: #81A1C1\">+=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">1<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">                cpm_stab<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">append<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">cpm<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #81A1C1\">elif<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">cpm <\/span><span style=\"color: #81A1C1\">&gt;<\/span><span style=\"color: #D8DEE9FF\"> max_cpm_efficiency_cal<\/span><span style=\"color: #ECEFF4\">):<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># out of range high. reset stabilized countrate time counter<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">                distance <\/span><span style=\"color: #81A1C1\">+=<\/span><span style=\"color: #D8DEE9FF\"> movestep<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">                <\/span><span style=\"color: #88C0D0\">movejig<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">distance<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">                s_stab <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">                cpm_stab <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">[]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #81A1C1\">elif<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">cpm <\/span><span style=\"color: #81A1C1\">&lt;<\/span><span style=\"color: #D8DEE9FF\"> min_cpm_efficiency_cal<\/span><span style=\"color: #ECEFF4\">):<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># out of range high. reset stabilized countrate time counter<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">                distance <\/span><span style=\"color: #81A1C1\">-=<\/span><span style=\"color: #D8DEE9FF\"> movestep<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">                <\/span><span style=\"color: #88C0D0\">movejig<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">distance<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">                s_stab <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">                cpm_stab <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">[]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">                <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #88C0D0\">print<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">cpm:<\/span><span style=\"color: #EBCB8B\">\\t<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> cpm<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #88C0D0\">print<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">stabilized_time:<\/span><span style=\"color: #EBCB8B\">\\t<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> s_stab<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #88C0D0\">print<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">distance:<\/span><span style=\"color: #EBCB8B\">\\t<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> distance<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> s_stab <\/span><span style=\"color: #81A1C1\">&gt;=<\/span><span style=\"color: #D8DEE9FF\"> efficiency_stab_time<\/span><span style=\"color: #ECEFF4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">                <\/span><span style=\"color: #616E88\">#distance = input(&quot;Please input distance in meters from GM_tube to source at stabilized reading&quot;)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">                cpm_stab <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> cpm_stab<\/span><span style=\"color: #ECEFF4\">[<\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\">last_secs_stab_time<\/span><span style=\"color: #ECEFF4\">:]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">                cpm_stab_avg <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">sum<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">cpm_stab<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #D8DEE9FF\">last_secs_stab_time<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">                <\/span><span style=\"color: #81A1C1\">break<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    cpm_efficiency_calc <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> cpm_stab_avg <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\"> cpm_background<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #616E88\">#calculate mean path length of gamma photons reaching the tube.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    mean_path <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">distance<\/span><span style=\"color: #81A1C1\">**<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">GM_tube_length<\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #81A1C1\">**<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #81A1C1\">**<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">distance<\/span><span style=\"color: #81A1C1\">**<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\">m<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9FF\">arcsinh<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">GM_tube_length<\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\">distance<\/span><span style=\"color: #ECEFF4\">))<\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #D8DEE9FF\">GM_tube_length<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #616E88\">#calculate attenuation from linear attenuation coefficient<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    gamma_att_air <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> m<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">exp<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\">\u00b51<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\">mean_path<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #616E88\">#calculate total gamma attenuation from air and Al filter.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    gamma_att_total <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> gamma_att_air<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\">gamma_att_Al<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    flux <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> gamma_att_total<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\">GM_tube_width<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">P_net<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">GM_tube_length<\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #ECEFF4\">))<\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #B48EAD\">4<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\">m<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9FF\">pi<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\">distance<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #ECEFF4\">((<\/span><span style=\"color: #D8DEE9FF\">GM_tubelength<\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #81A1C1\">**<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> distance<\/span><span style=\"color: #81A1C1\">**<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #81A1C1\">**<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #ECEFF4\">))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #616E88\"># gamma flux in photons.s^-1 crossing the GM tube.  Accounting for planar cross section of GM Tube (instead of solid angle) and attenuation from air and beta filter of gamma photons.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    theoretical_cpm <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">60<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\">flux <\/span><span style=\"color: #616E88\"># assuming GM tube efficiency of 1, All photons would give rise to ionization events inside the GM tube<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">s <\/span><span style=\"color: #81A1C1\">!=<\/span><span style=\"color: #D8DEE9FF\"> efficiency_placing_time<\/span><span style=\"color: #ECEFF4\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        efficiency <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> cpm_efficiency_calc<\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #D8DEE9FF\">theoretical_cpm<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #88C0D0\">print<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">computed efficiency:<\/span><span style=\"color: #EBCB8B\">\\t<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> efficiency<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #81A1C1\">return<\/span><span style=\"color: #ECEFF4\">((<\/span><span style=\"color: #D8DEE9FF\">efficiency<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\">distance<\/span><span style=\"color: #ECEFF4\">))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">else<\/span><span style=\"color: #ECEFF4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #88C0D0\">print<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">efficiency calibration failed.<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #81A1C1\">return<\/span><span style=\"color: #ECEFF4\">((<\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\">distance<\/span><span style=\"color: #ECEFF4\">))<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #616E88\"># Compute efficiency of detection at a count rate sufficiently high enough above background but not as high as dead time effects become significant.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">efficiency_placing_time <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">600<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">efficiency_stab_time <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">180<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">last_secs_stab_time <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">60<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">min_cpm_efficiency_cal <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">8<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\">cpm_background<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">max_cpm_efficiency_cal <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">16<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\">cpm_background<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">chars <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">None<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">chars <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">input<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">Step 2.0 - efficiency computation: please put the source at <\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> distance <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">cm from the GM tube, normal to the tube, withint the collimator. press ENTER to start<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #88C0D0\">movejig<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">distance<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># initial position<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">efficiency<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\">distance<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">efficiency_step<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">distance<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># gets efficiency, -1 if failed, and jig to source distance<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">while<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">efficiency <\/span><span style=\"color: #81A1C1\">==<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #ECEFF4\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #88C0D0\">print<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">efficiency calculation step failed. repeating<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">efficiency<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\">distance<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">efficiency_step<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">distance<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #616E88\">#STEP 3 : record countrate while stepping the source jig towards the GM tube<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">step3_wait_time <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">120<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">step3_last_seconds_measure <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">60<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">step3_last_seconds_measure <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">min<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #B48EAD\">120<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\">step3_last_seconds_measure<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># ensure the total seconds we sample is lower than step3_wait_time<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">x_distance <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> np<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">arange<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">max_distance<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\">min_distance<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #B48EAD\">0.005<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">y_cpm_m <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> np<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">empty<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #88C0D0\">len<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">x_distance<\/span><span style=\"color: #ECEFF4\">))<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># array of average of count rate for each measurement sampling<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">y_cpm_m<\/span><span style=\"color: #ECEFF4\">[:]<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> np<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9FF\">nan<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">y_std_m <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> np<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">empty<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #88C0D0\">len<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">x_distance<\/span><span style=\"color: #ECEFF4\">))<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># array of standard deviation of count rate for each measurement sampling<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">y_std_m<\/span><span style=\"color: #ECEFF4\">[:]<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> np<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9FF\">nan<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">y_cpm_t <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> np<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">empty<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #88C0D0\">len<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">x_distance<\/span><span style=\"color: #ECEFF4\">))<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># array of theoretical cpms derated with GM tube efficiency<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">y_cpm_t<\/span><span style=\"color: #ECEFF4\">[:]<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> np<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9FF\">nan<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">y_cpm_tm <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> np<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">empty<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #88C0D0\">len<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">x_distance<\/span><span style=\"color: #ECEFF4\">))<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># array of theoretical cpms derated with GM tube efficiency and dead time effects<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">y_cpm_tm<\/span><span style=\"color: #ECEFF4\">[:]<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> np<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9FF\">nan<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">distance_cpm_avg_m <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> np<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">stack<\/span><span style=\"color: #ECEFF4\">([<\/span><span style=\"color: #D8DEE9FF\">x_distance<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\">y_cpm_m<\/span><span style=\"color: #ECEFF4\">],<\/span><span style=\"color: #D8DEE9\">axis<\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># tabular data for cpm (average) as a function of source\/GM tube distance<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">distance_cpm_std_m <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\">  np<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">stack<\/span><span style=\"color: #ECEFF4\">([<\/span><span style=\"color: #D8DEE9FF\">x_distance<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\">y_std_m<\/span><span style=\"color: #ECEFF4\">],<\/span><span style=\"color: #D8DEE9\">axis<\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># tabular data for cpm (std dev) as a function of source\/GM tube distance<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">distance_cpm_t <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> np<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">stack<\/span><span style=\"color: #ECEFF4\">([<\/span><span style=\"color: #D8DEE9FF\">x_distance<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\">y_cpm_t<\/span><span style=\"color: #ECEFF4\">],<\/span><span style=\"color: #D8DEE9\">axis<\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># tabular data for cpm (theoretical), derated by GM tube efficiency as a function of distance<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">distance_cpm_tm <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> np<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">stack<\/span><span style=\"color: #ECEFF4\">([<\/span><span style=\"color: #D8DEE9FF\">x_distance<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\">y_cpm_tm<\/span><span style=\"color: #ECEFF4\">],<\/span><span style=\"color: #D8DEE9\">axis<\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># tabular data for cpm (theoretical), derated by GM tube efficiency and accounting for dead time effects<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">distance <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> max_distance <\/span><span style=\"color: #616E88\"># retract actuator to minimum to get longest source to GM tube distance.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">not<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #88C0D0\">movejig<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">distance<\/span><span style=\"color: #ECEFF4\">)):<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># no actuation error<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    idx <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">while<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">distance <\/span><span style=\"color: #81A1C1\">&gt;<\/span><span style=\"color: #D8DEE9FF\"> min_distance<\/span><span style=\"color: #ECEFF4\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #88C0D0\">movejig<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">distance<\/span><span style=\"color: #ECEFF4\">)):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #81A1C1\">break<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># actuation error, break loop<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        distance <\/span><span style=\"color: #81A1C1\">-=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0.05<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        cpm_stab <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">[]<\/span><span style=\"color: #D8DEE9FF\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #616E88\">#<\/span><span style=\"color: #81A1C1\">TODO<\/span><span style=\"color: #616E88\"> : reset deque() in GMobile after jig move, to get rid of the inertia induced by the sliding window sampling<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #81A1C1\">while<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">s <\/span><span style=\"color: #81A1C1\">&lt;<\/span><span style=\"color: #D8DEE9FF\"> step3_wait_time<\/span><span style=\"color: #ECEFF4\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">s <\/span><span style=\"color: #81A1C1\">&gt;=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">step3_wait_time <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\"> step3_last_seconds_measure<\/span><span style=\"color: #ECEFF4\">)):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">                cpm_stab<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">append<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">GM<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">process_events<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #81A1C1\">False<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #81A1C1\">False<\/span><span style=\"color: #ECEFF4\">))<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># This call should take exactly one second.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #81A1C1\">else<\/span><span style=\"color: #ECEFF4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">                time<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">sleep<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        cpm_avg <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> np<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">average<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">cpm_stab<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        cpm_std <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> np<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">std<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">cpm_stab<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        distance_cpm_avg_m<\/span><span style=\"color: #ECEFF4\">[<\/span><span style=\"color: #D8DEE9FF\">idx<\/span><span style=\"color: #ECEFF4\">][<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #ECEFF4\">]<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> cpm_avg<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        distance_cpm_std_m<\/span><span style=\"color: #ECEFF4\">[<\/span><span style=\"color: #D8DEE9FF\">idx<\/span><span style=\"color: #ECEFF4\">][<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #ECEFF4\">]<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> cpm_std<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #616E88\">#calculate mean path length of gamma photons reaching the tube.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        mean_path <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">distance<\/span><span style=\"color: #81A1C1\">**<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">GM_tube_length<\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #81A1C1\">**<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #81A1C1\">**<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">distance<\/span><span style=\"color: #81A1C1\">**<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\">m<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9FF\">arcsinh<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">GM_tube_length<\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\">distance<\/span><span style=\"color: #ECEFF4\">))<\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #D8DEE9FF\">GM_tube_length<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #616E88\">#calculate attenuation from linear attenuation coefficient<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        gamma_att_air <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> m<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">exp<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\">\u00b51<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\">mean_path<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #616E88\">#calculate total gamma attenuation from air and Al filter.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        gamma_att_total <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> gamma_att_air<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\">gamma_att_Al<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        flux <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> gamma_att_total<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\">GM_tube_width<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">P_net<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">GM_tube_length<\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #ECEFF4\">))<\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #B48EAD\">4<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\">m<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9FF\">pi<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\">distance<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #ECEFF4\">((<\/span><span style=\"color: #D8DEE9FF\">GM_tubelength<\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #81A1C1\">**<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> distance<\/span><span style=\"color: #81A1C1\">**<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #81A1C1\">**<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #ECEFF4\">))<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #616E88\"># gamma flux in photons.s^-1 crossing the GM tube. Accounting for planar cross section of GM Tube (instead of solid angle) and attenuation from air and beta filter of gamma photons.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        theoretical_cpm_eff <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">60<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\">flux<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\">efficiency <\/span><span style=\"color: #616E88\"># theoretical cpm (derated with GM tube efficiency estimated in step 2.0)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        distance_cpm_t<\/span><span style=\"color: #ECEFF4\">[<\/span><span style=\"color: #D8DEE9FF\">idx<\/span><span style=\"color: #ECEFF4\">][<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #ECEFF4\">]<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> theoretical_cpm_eff<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        distance_cpm_tm<\/span><span style=\"color: #ECEFF4\">[<\/span><span style=\"color: #D8DEE9FF\">idx<\/span><span style=\"color: #ECEFF4\">][<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #ECEFF4\">]<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">model1_estimated_GM_CPM<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">theoretical_cpm_eff<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># theoretical cpm from above with dead time compensation<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">def<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">compare_cpm_measured_theoretical<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9\">theoretical<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9\">measured<\/span><span style=\"color: #ECEFF4\">):<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    devsum <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    devratiosum <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #88C0D0\">len<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">theoretical<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">!=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">len<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">measured<\/span><span style=\"color: #ECEFF4\">)):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #81A1C1\">return<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">for<\/span><span style=\"color: #D8DEE9FF\"> idx <\/span><span style=\"color: #81A1C1\">in<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">range<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #B48EAD\">0<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #88C0D0\">len<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">theoretical<\/span><span style=\"color: #ECEFF4\">)):<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        devratiosum <\/span><span style=\"color: #81A1C1\">+=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">abs<\/span><span style=\"color: #ECEFF4\">((<\/span><span style=\"color: #D8DEE9FF\">measured<\/span><span style=\"color: #ECEFF4\">[<\/span><span style=\"color: #D8DEE9FF\">idx<\/span><span style=\"color: #ECEFF4\">][<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #ECEFF4\">]<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\"> theoretical<\/span><span style=\"color: #ECEFF4\">[<\/span><span style=\"color: #D8DEE9FF\">idx<\/span><span style=\"color: #ECEFF4\">][<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #ECEFF4\">])<\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #D8DEE9FF\">measured<\/span><span style=\"color: #ECEFF4\">[<\/span><span style=\"color: #D8DEE9FF\">idx<\/span><span style=\"color: #ECEFF4\">][<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #ECEFF4\">])<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        devsum <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">measured<\/span><span style=\"color: #ECEFF4\">[<\/span><span style=\"color: #D8DEE9FF\">idx<\/span><span style=\"color: #ECEFF4\">][<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #ECEFF4\">]<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\"> theoretical<\/span><span style=\"color: #ECEFF4\">[<\/span><span style=\"color: #D8DEE9FF\">idx<\/span><span style=\"color: #ECEFF4\">][<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #ECEFF4\">])<\/span><span style=\"color: #81A1C1\">**<\/span><span style=\"color: #B48EAD\">2<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    mape <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> devratiosum<\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #88C0D0\">len<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">theoretical<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">return<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">devsum<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\">mape<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">def<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">plotcurves<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9\">curve_x<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">curve_y1<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">curve_y2<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">color_curve_1<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">color_curve_2<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">label_curve_1<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">label_curve_2<\/span><span style=\"color: #ECEFF4\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    plt<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">plot<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">curve_x<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> curve_y1<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> color_curve_1<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">label<\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\">label_curve_1<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    plt<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">plot<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">curve_x<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> curve_y2<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> color_curve_2<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">label<\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\">label_curve_2<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    plt<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">xlabel<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #A3BE8C\">distance (m)<\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    plt<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">ylabel<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #A3BE8C\">count rate (cpm)<\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    plt<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">legend<\/span><span style=\"color: #ECEFF4\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    plt<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">grid<\/span><span style=\"color: #ECEFF4\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    plt<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">show<\/span><span style=\"color: #ECEFF4\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #88C0D0\">print<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #88C0D0\">compare_cpm_measured_theoretical<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">distance_cpm_tm<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\">distance_cpm_avg_m<\/span><span style=\"color: #ECEFF4\">))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #88C0D0\">plotcurves<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">distance_cpm_t<\/span><span style=\"color: #ECEFF4\">[:,<\/span><span style=\"color: #B48EAD\">0<\/span><span style=\"color: #ECEFF4\">],<\/span><span style=\"color: #D8DEE9FF\">distance_cpm_avg_m<\/span><span style=\"color: #ECEFF4\">[:,<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #ECEFF4\">],<\/span><span style=\"color: #D8DEE9FF\">distance_cpm_tm<\/span><span style=\"color: #ECEFF4\">[:,<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #ECEFF4\">],<\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #A3BE8C\">r-<\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #A3BE8C\">g-<\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">measured<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">theoretical_compensated<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p>This is the main GM counter interfacing script, with Mariadb logging, individual pulse timestamping Geotagging, and Lora telemetry (work in progress)<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><textarea class=\"code-block-pro-copy-button-textarea\" aria-hidden=\"true\" readonly># coding: utf-8\n\n\nimport RPi.GPIO as GPIO\nimport scipy as sp\nimport signal\nimport sys\nimport time\nimport datetime\nfrom collections import deque \nimport struct\nimport statistics\n\n# Module Imports\nimport mariadb\n#from mariadb.connector.aio import connect\nimport sys\nimport re\n\n# Lora Imports\n\nfrom SX127x.LoRa import *\n#from SX127x.LoRaArgumentParser import LoRaArgumentParser\nfrom SX127x.board_config import BOARD\n\ndef signal_handler(sig, frame):\n    GPIO.cleanup()\n    sys.exit(0)\n\n\ndef pulse_detected_callback(channel):\n    global pulse_events\n    pulse_events.append(time.time() &#8211; start_time_epoch)\n\n\ndef dms2dec(dms_str):\n    \n    \n    dms_str = re.sub(r&#8217;\\s&#8217;, &#8221;, dms_str)\n    \n    sign = -1 if re.search(&#8216;[swSW]&#8217;, dms_str) else 1\n    \n    numbers = [*filter(len, re.split(&#8216;\\D+&#8217;, dms_str, maxsplit=4))]\n\n    degree = numbers[0]\n    minute = numbers[1] if len(numbers) >= 2 else &#8216;0&#8217;\n    second = numbers[2] if len(numbers) >= 3 else &#8216;0&#8217;\n    frac_seconds = numbers[3] if len(numbers) >= 4 else &#8216;0&#8217;\n    \n    second += &#8220;.&#8221; + frac_seconds\n    return sign * (int(degree) + float(minute) \/ 60 + float(second) \/ 3600)\n\n# Connect to MariaDB Platform\ntry:\n    conn = mariadb.connect(\n    #conn = connect(\n        user=&#8221;gmobile_user&#8221;,\n        password=&#8221;gmobile_passwd&#8221;,\n        host=&#8221;127.0.0.1&#8243;,\n        port=3306,\n        database=&#8221;gmobile&#8221;\n\n    )\nexcept mariadb.Error as e:\n    print(f&#8221;Error connecting to MariaDB Platform: {e}&#8221;)\n    sys.exit(1)\n\n# Get Cursor\ncur = conn.cursor()\n\nstart_time_epoch = time.time()\npulse_events = deque()\ncps = 0\ncpm = 0\n#process_pulses = True\n\n#paralyzable model\n# m = n*exp(-nt)\n# using lambert(w) \n#y =  w * exp(w)\n#-nt = w\n\n#y = -nt * exp(-nt)\n\n#-nt = lambert(y)\n#n = -lambert(y)\/t\n\n#scipy.special.lambertw(z, k=0, tol=1e-8)\n\n\n#while True:\n#    GPIO.wait_for_edge(PULSE_GPIO, GPIO.FALLING)\n#    print(&#8220;Button pressed!&#8221;)\n#    sp.special.lambertw(z, k=0, tol=1e-8)\n\nPULSE_GPIO = 16\nlat = dms2dec(&#8220;51\u00b024&#8217;04.30\\&#8221;N&#8221;)\nlong = dms2dec(&#8220;30\u00b002&#8217;50.70\\&#8221;E&#8221;)\n\n\ndef setupGPIOEventDetect():\n\n\n    GPIO.setmode(GPIO.BOARD)\n    GPIO.setup(PULSE_GPIO, GPIO.IN)\n    GPIO.add_event_detect(PULSE_GPIO, GPIO.RISING, callback=pulse_detected_callback)\n\n\ndef removeGPIOEventDetect():\n\n    GPIO.remove_event_detect(PULSE_GPIO)\n\n\ndef measurePulseWidth(total_pulses,max_fails=20,rise_timeout_ms=20000,fall_timeout_ms=20):\n\n    removeGPIOEventDetect()\n    s = 0\n    fail = 0\n    pulsewidths = []\n\n    while(s &lt; total_pulses and fail &lt; max_fails):\n        channel = GPIO.wait_for_edge(PULSE_GPIO,GPIO.RISING,timeout=rise_timeout_ms) # assuming there is at least one pulse registered every rise_timeout_ms\n        if (channel is None):\n            fail += 1\n            continue\n        pulsestart = time.time_ns()\n        channel = GPIO.wait_for_edge(PULSE_GPIO,GPIO.FALLING,timeout=fall_timeout_ms) # assuming the pulse width is less fall_timeout_ms\n        if (channel is None):\n            fail += 1\n            continue\n        pulsewidths.append((time.time_ns() &#8211; pulsestart)\/1000) # save pulsewidth value in \u00b5s\n        s+= 1 # sucessful pulsewidth measure\n\n        #this pulse timing method may be problematic if the real time separation between RISING and FALLING edge is shorter than execution time between the two\n        #wait_for_edge calls. thread should be set to high priority. Overall, dead time will be overestimated.\n\n    setupGPIOEventDetect()\n    return (pulsewidths[int(len(pulsewidths)\/2)],statistics.pstdev(pulsewidths)) # returns mean pulsewidth value in \u00b5s and standard deviation.\n\n\n\n# LORA INIT\n\n#BOARD.setup()\n#BOARD.reset()\n##parser = LoRaArgumentParser(&#8220;Lora tester&#8221;)\n\n\n\n\n\n\n\n&#8220;&#8221;&#8221;\nclass mylora(LoRa):\n    \n    global current_data\n    \n    def __init__(self, verbose=False):\n        super(mylora, self).__init__(verbose)\n        self.set_mode(MODE.SLEEP)\n        self.set_dio_mapping([0] * 6)\n\n    def on_rx_done(self):\n        BOARD.led_on()\n        #print(&#8220;\\nRxDone&#8221;)\n        self.clear_irq_flags(RxDone=1)\n        payload = self.read_payload(nocheck=True )# Receive INF\n        print (&#8220;Receive: &#8220;)\n        mens=bytes(payload).decode(&#8220;utf-8&#8243;,&#8217;ignore&#8217;)\n        mens=mens[2:-1] #to discard \\x00\\x00 and \\x00 at the end\n        print(mens)\n        BOARD.led_off()\n        if mens==&#8221;INF&#8221;:\n            print(&#8220;Received data request INF&#8221;)\n            time.sleep(2)\n            print (&#8220;Send mens: DATA RASPBERRY PI&#8221;)\n            self.write_payload([255, 255, 0, 0, 68, 65, 84, 65, 32, 82, 65, 83, 80, 66, 69, 82, 82, 89, 32, 80, 73, 0]) # Send DATA RASPBERRY PI\n            self.set_mode(MODE.TX)\n        time.sleep(2)\n        self.reset_ptr_rx()\n        self.set_mode(MODE.RXCONT)\n\n    def on_tx_done(self):\n        print(&#8220;\\nTxDone&#8221;)\n        print(self.get_irq_flags())\n\n    def on_cad_done(self):\n        print(&#8220;\\non_CadDone&#8221;)\n        print(self.get_irq_flags())\n\n    def on_rx_timeout(self):\n        print(&#8220;\\non_RxTimeout&#8221;)\n        print(self.get_irq_flags())\n\n    def on_valid_header(self):\n        print(&#8220;\\non_ValidHeader&#8221;)\n        print(self.get_irq_flags())\n\n    def on_payload_crc_error(self):\n        print(&#8220;\\non_PayloadCrcError&#8221;)\n        print(self.get_irq_flags())\n\n    def on_fhss_change_channel(self):\n        print(&#8220;\\non_FhssChangeChannel&#8221;)\n        print(self.get_irq_flags())\n\n    def start(self):          \n        while True:\n            self.reset_ptr_rx()\n            self.set_mode(MODE.RXCONT) # Receiver mode\n            while True:\n                pass;\n\n    def send(data):\n        data = [255, 255, 0, 0] + data + [0] \n        self.write_payload([data]) # Send DATA\n        time.sleep(2)\n        self.reset_ptr_rx()\n        self.set_mode(MODE.RXCONT)\n\nlora = mylora(verbose=False)\n#args = parser.parse_args(lora) # configs in LoRaArgumentParser.py\n\n#     Slow+long range  Bw = 125 kHz, Cr = 4\/8, Sf = 4096chips\/symbol, CRC on. 13 dBm\nlora.set_pa_config(pa_select=1, max_power=21, output_power=15)\nlora.set_bw(BW.BW125)\nlora.set_coding_rate(CODING_RATE.CR4_8)\nlora.set_spreading_factor(12)\nlora.set_rx_crc(True)\n#lora.set_lna_gain(GAIN.G1)\n#lora.set_implicit_header_mode(False)\nlora.set_low_data_rate_optim(True)\n\n#  Medium Range  Defaults after init are 434.0MHz, Bw = 125 kHz, Cr = 4\/5, Sf = 128chips\/symbol, CRC on 13 dBm\n#lora.set_pa_config(pa_select=1)\n\n\n\nassert(lora.get_agc_auto_on() == 1)\n\ntry:\n    print(&#8220;START&#8221;)\n    lora.start()\nexcept KeyboardInterrupt:\n    sys.stdout.flush()\n    print(&#8220;Exit&#8221;)\n    sys.stderr.write(&#8220;KeyboardInterrupt\\n&#8221;)\nfinally:\n    sys.stdout.flush()\n    print(&#8220;Exit&#8221;)\n    lora.set_mode(MODE.SLEEP)\nBOARD.teardown()\n&#8220;&#8221;&#8221;\n\n   \nsignal.signal(signal.SIGINT, signal_handler)\n\ndef process_events(log=False,lorasend=False):\n    global cps\n    global cpm\n    nowtime = time.time()\n    prune_before_time = nowtime &#8211; start_time_epoch &#8211; 60.0\n    for pulse in list(pulse_events):\n        if(pulse &lt; prune_before_time):\n            pulse_events.popleft()\n    cps = len(pulse_events)\/60.0\n    cpm = len(pulse_events)\n    print(cpm)\n    \n    if not(int(time.time()) % 60) and prune_before_time > 0:\n        # log last minute cpm to db. wait at least 60 sec from start\n        # to get steady state data.\n        print(&#8220;last minute cpm:&#8221; + str(cpm))\n        if(lorasend):        \n            epoch_ms = int(time.time()*1000.0)\n            buffer_data = struct.pack(&#8220;&lt;Q&#8221;, epoch_ms) # pack epoch_ms into byte array little endian\n            buffer_data += struct.pack(&#8220;&lt;L&#8221;, cpm) # append cpm into byte array little endian\n            #lora.send(buffer_data)\n            print(buffer_data)\n        if(log):\n            sql = &#8220;INSERT INTO data_cpm (timestamp_utc,count_per_minute,coordinates) VALUES(%s, %s, ST_PointFromWKB(ST_AsBinary(POINT(&#8221; + str(lat) + &#8220;,&#8221; + str(long) + &#8220;)), 4326))&#8221;;\n            val = (str(datetime.datetime.now()),str(cpm))\n            cur.execute(sql, val)\n            conn.commit()\n    \n    processing_delay = time.time() &#8211; nowtime\n    print(processing_delay)\n    proc_delay_mul = int(processing_delay)\n    time.sleep(1 + proc_delay_mul &#8211; processing_delay)\n    # ensure isochronous sampling, add n skip seconds in case of the block taking a really long time&#8230;\n    # asynchronous mariadb cursor should prevent this occurence.\n    if(prune_before_time > 0): # 60 sec have elapsed\n        return cpm\n    else:\n        return -1\n\n    \n#while process_pulses:\n#    process_events()\n#signal.pause()\n<\/textarea><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #616E88\"># coding: utf-8<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">import<\/span><span style=\"color: #D8DEE9FF\"> RPi<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9FF\">GPIO <\/span><span style=\"color: #81A1C1\">as<\/span><span style=\"color: #D8DEE9FF\"> GPIO<\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">import<\/span><span style=\"color: #D8DEE9FF\"> scipy <\/span><span style=\"color: #81A1C1\">as<\/span><span style=\"color: #D8DEE9FF\"> sp<\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">import<\/span><span style=\"color: #D8DEE9FF\"> signal<\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">import<\/span><span style=\"color: #D8DEE9FF\"> sys<\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">import<\/span><span style=\"color: #D8DEE9FF\"> time<\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">import<\/span><span style=\"color: #D8DEE9FF\"> datetime<\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">from<\/span><span style=\"color: #D8DEE9FF\"> collections <\/span><span style=\"color: #81A1C1\">import<\/span><span style=\"color: #D8DEE9FF\"> deque <\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">import<\/span><span style=\"color: #D8DEE9FF\"> struct<\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">import<\/span><span style=\"color: #D8DEE9FF\"> statistics<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #616E88\"># Module Imports<\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">import<\/span><span style=\"color: #D8DEE9FF\"> mariadb<\/span><\/span>\n<span class=\"line\"><span style=\"color: #616E88\">#from mariadb.connector.aio import connect<\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">import<\/span><span style=\"color: #D8DEE9FF\"> sys<\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">import<\/span><span style=\"color: #D8DEE9FF\"> re<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #616E88\"># Lora Imports<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">from<\/span><span style=\"color: #D8DEE9FF\"> SX127x<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9FF\">LoRa <\/span><span style=\"color: #81A1C1\">import<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">*<\/span><\/span>\n<span class=\"line\"><span style=\"color: #616E88\">#from SX127x.LoRaArgumentParser import LoRaArgumentParser<\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">from<\/span><span style=\"color: #D8DEE9FF\"> SX127x<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9FF\">board_config <\/span><span style=\"color: #81A1C1\">import<\/span><span style=\"color: #D8DEE9FF\"> BOARD<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">def<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">signal_handler<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9\">sig<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">frame<\/span><span style=\"color: #ECEFF4\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    GPIO<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">cleanup<\/span><span style=\"color: #ECEFF4\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    sys<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">exit<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #B48EAD\">0<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">def<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">pulse_detected_callback<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9\">channel<\/span><span style=\"color: #ECEFF4\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">global<\/span><span style=\"color: #D8DEE9FF\"> pulse_events<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    pulse_events<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">append<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">time<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">time<\/span><span style=\"color: #ECEFF4\">()<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\"> start_time_epoch<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">def<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">dms2dec<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9\">dms_str<\/span><span style=\"color: #ECEFF4\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    dms_str <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> re<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">sub<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #81A1C1\">r<\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #EBCB8B\">\\s<\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">&#39;&#39;<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> dms_str<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    sign <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> re<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">search<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #A3BE8C\">[swSW]<\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> dms_str<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">else<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">1<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    numbers <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">[<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #88C0D0\">filter<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #88C0D0\">len<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> re<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">split<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #A3BE8C\">\\D+<\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> dms_str<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">maxsplit<\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #B48EAD\">4<\/span><span style=\"color: #ECEFF4\">))]<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    degree <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> numbers<\/span><span style=\"color: #ECEFF4\">[<\/span><span style=\"color: #B48EAD\">0<\/span><span style=\"color: #ECEFF4\">]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    minute <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> numbers<\/span><span style=\"color: #ECEFF4\">[<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #ECEFF4\">]<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">len<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">numbers<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">&gt;=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">else<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #A3BE8C\">0<\/span><span style=\"color: #ECEFF4\">&#39;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    second <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> numbers<\/span><span style=\"color: #ECEFF4\">[<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #ECEFF4\">]<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">len<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">numbers<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">&gt;=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">3<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">else<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #A3BE8C\">0<\/span><span style=\"color: #ECEFF4\">&#39;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    frac_seconds <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> numbers<\/span><span style=\"color: #ECEFF4\">[<\/span><span style=\"color: #B48EAD\">3<\/span><span style=\"color: #ECEFF4\">]<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">len<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">numbers<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">&gt;=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">4<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">else<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #A3BE8C\">0<\/span><span style=\"color: #ECEFF4\">&#39;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    second <\/span><span style=\"color: #81A1C1\">+=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">.<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> frac_seconds<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">return<\/span><span style=\"color: #D8DEE9FF\"> sign <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #88C0D0\">int<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">degree<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">float<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">minute<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">60<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">float<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">second<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">3600<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #616E88\"># Connect to MariaDB Platform<\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">try<\/span><span style=\"color: #ECEFF4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    conn <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> mariadb<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">connect<\/span><span style=\"color: #ECEFF4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #616E88\">#conn = connect(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #D8DEE9\">user<\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">gmobile_user<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #ECEFF4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #D8DEE9\">password<\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">gmobile_passwd<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #ECEFF4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #D8DEE9\">host<\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">127.0.0.1<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #ECEFF4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #D8DEE9\">port<\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #B48EAD\">3306<\/span><span style=\"color: #ECEFF4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #D8DEE9\">database<\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">gmobile<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">except<\/span><span style=\"color: #D8DEE9FF\"> mariadb<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9FF\">Error <\/span><span style=\"color: #81A1C1\">as<\/span><span style=\"color: #D8DEE9FF\"> e<\/span><span style=\"color: #ECEFF4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #88C0D0\">print<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #81A1C1\">f<\/span><span style=\"color: #A3BE8C\">&quot;Error connecting to MariaDB Platform: <\/span><span style=\"color: #EBCB8B\">{<\/span><span style=\"color: #D8DEE9FF\">e<\/span><span style=\"color: #EBCB8B\">}<\/span><span style=\"color: #A3BE8C\">&quot;<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    sys<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">exit<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #616E88\"># Get Cursor<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">cur <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> conn<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">cursor<\/span><span style=\"color: #ECEFF4\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">start_time_epoch <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> time<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">time<\/span><span style=\"color: #ECEFF4\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">pulse_events <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">deque<\/span><span style=\"color: #ECEFF4\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">cps <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">cpm <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0<\/span><\/span>\n<span class=\"line\"><span style=\"color: #616E88\">#process_pulses = True<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #616E88\">#paralyzable model<\/span><\/span>\n<span class=\"line\"><span style=\"color: #616E88\"># m = n*exp(-nt)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #616E88\"># using lambert(w) <\/span><\/span>\n<span class=\"line\"><span style=\"color: #616E88\">#y =  w * exp(w)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #616E88\">#-nt = w<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #616E88\">#y = -nt * exp(-nt)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #616E88\">#-nt = lambert(y)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #616E88\">#n = -lambert(y)\/t<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #616E88\">#scipy.special.lambertw(z, k=0, tol=1e-8)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #616E88\">#while True:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #616E88\">#    GPIO.wait_for_edge(PULSE_GPIO, GPIO.FALLING)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #616E88\">#    print(&quot;Button pressed!&quot;)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #616E88\">#    sp.special.lambertw(z, k=0, tol=1e-8)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">PULSE_GPIO <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">16<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">lat <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">dms2dec<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">51\u00b024&#39;04.30<\/span><span style=\"color: #EBCB8B\">\\&quot;<\/span><span style=\"color: #A3BE8C\">N<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">long <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">dms2dec<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">30\u00b002&#39;50.70<\/span><span style=\"color: #EBCB8B\">\\&quot;<\/span><span style=\"color: #A3BE8C\">E<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">def<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">setupGPIOEventDetect<\/span><span style=\"color: #ECEFF4\">():<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    GPIO<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">setmode<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">GPIO<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9FF\">BOARD<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    GPIO<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">setup<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">PULSE_GPIO<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> GPIO<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9FF\">IN<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    GPIO<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">add_event_detect<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">PULSE_GPIO<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> GPIO<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9FF\">RISING<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">callback<\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\">pulse_detected_callback<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">def<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">removeGPIOEventDetect<\/span><span style=\"color: #ECEFF4\">():<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    GPIO<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">remove_event_detect<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">PULSE_GPIO<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">def<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">measurePulseWidth<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9\">total_pulses<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9\">max_fails<\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #B48EAD\">20<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9\">rise_timeout_ms<\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #B48EAD\">20000<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9\">fall_timeout_ms<\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #B48EAD\">20<\/span><span style=\"color: #ECEFF4\">):<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #88C0D0\">removeGPIOEventDetect<\/span><span style=\"color: #ECEFF4\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    s <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    fail <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    pulsewidths <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">[]<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">while<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">s <\/span><span style=\"color: #81A1C1\">&lt;<\/span><span style=\"color: #D8DEE9FF\"> total_pulses <\/span><span style=\"color: #81A1C1\">and<\/span><span style=\"color: #D8DEE9FF\"> fail <\/span><span style=\"color: #81A1C1\">&lt;<\/span><span style=\"color: #D8DEE9FF\"> max_fails<\/span><span style=\"color: #ECEFF4\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        channel <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> GPIO<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">wait_for_edge<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">PULSE_GPIO<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\">GPIO<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9FF\">RISING<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9\">timeout<\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\">rise_timeout_ms<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># assuming there is at least one pulse registered every rise_timeout_ms<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">channel <\/span><span style=\"color: #81A1C1\">is<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">None<\/span><span style=\"color: #ECEFF4\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            fail <\/span><span style=\"color: #81A1C1\">+=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">1<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #81A1C1\">continue<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        pulsestart <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> time<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">time_ns<\/span><span style=\"color: #ECEFF4\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        channel <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> GPIO<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">wait_for_edge<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">PULSE_GPIO<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\">GPIO<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9FF\">FALLING<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9\">timeout<\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\">fall_timeout_ms<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># assuming the pulse width is less fall_timeout_ms<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">channel <\/span><span style=\"color: #81A1C1\">is<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">None<\/span><span style=\"color: #ECEFF4\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            fail <\/span><span style=\"color: #81A1C1\">+=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">1<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #81A1C1\">continue<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        pulsewidths<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">append<\/span><span style=\"color: #ECEFF4\">((<\/span><span style=\"color: #D8DEE9FF\">time<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">time_ns<\/span><span style=\"color: #ECEFF4\">()<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\"> pulsestart<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #B48EAD\">1000<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># save pulsewidth value in \u00b5s<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        s<\/span><span style=\"color: #81A1C1\">+=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># sucessful pulsewidth measure<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #616E88\">#this pulse timing method may be problematic if the real time separation between RISING and FALLING edge is shorter than execution time between the two<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #616E88\">#wait_for_edge calls. thread should be set to high priority. Overall, dead time will be overestimated.<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #88C0D0\">setupGPIOEventDetect<\/span><span style=\"color: #ECEFF4\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">return<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">pulsewidths<\/span><span style=\"color: #ECEFF4\">[<\/span><span style=\"color: #88C0D0\">int<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #88C0D0\">len<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">pulsewidths<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #ECEFF4\">)],<\/span><span style=\"color: #D8DEE9FF\">statistics<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">pstdev<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">pulsewidths<\/span><span style=\"color: #ECEFF4\">))<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># returns mean pulsewidth value in \u00b5s and standard deviation.<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #616E88\"># LORA INIT<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #616E88\">#BOARD.setup()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #616E88\">#BOARD.reset()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #616E88\">##parser = LoRaArgumentParser(&quot;Lora tester&quot;)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">&quot;&quot;&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">class mylora(LoRa):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">    global current_data<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">    def __init__(self, verbose=False):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">        super(mylora, self).__init__(verbose)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">        self.set_mode(MODE.SLEEP)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">        self.set_dio_mapping([0] * 6)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">    def on_rx_done(self):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">        BOARD.led_on()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">        #print(&quot;<\/span><span style=\"color: #EBCB8B\">\\n<\/span><span style=\"color: #A3BE8C\">RxDone&quot;)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">        self.clear_irq_flags(RxDone=1)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">        payload = self.read_payload(nocheck=True )# Receive INF<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">        print (&quot;Receive: &quot;)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">        mens=bytes(payload).decode(&quot;utf-8&quot;,&#39;ignore&#39;)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">        mens=mens[2:-1] #to discard <\/span><span style=\"color: #EBCB8B\">\\x00\\x00<\/span><span style=\"color: #A3BE8C\"> and <\/span><span style=\"color: #EBCB8B\">\\x00<\/span><span style=\"color: #A3BE8C\"> at the end<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">        print(mens)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">        BOARD.led_off()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">        if mens==&quot;INF&quot;:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">            print(&quot;Received data request INF&quot;)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">            time.sleep(2)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">            print (&quot;Send mens: DATA RASPBERRY PI&quot;)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">            self.write_payload([255, 255, 0, 0, 68, 65, 84, 65, 32, 82, 65, 83, 80, 66, 69, 82, 82, 89, 32, 80, 73, 0]) # Send DATA RASPBERRY PI<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">            self.set_mode(MODE.TX)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">        time.sleep(2)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">        self.reset_ptr_rx()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">        self.set_mode(MODE.RXCONT)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">    def on_tx_done(self):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">        print(&quot;<\/span><span style=\"color: #EBCB8B\">\\n<\/span><span style=\"color: #A3BE8C\">TxDone&quot;)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">        print(self.get_irq_flags())<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">    def on_cad_done(self):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">        print(&quot;<\/span><span style=\"color: #EBCB8B\">\\n<\/span><span style=\"color: #A3BE8C\">on_CadDone&quot;)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">        print(self.get_irq_flags())<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">    def on_rx_timeout(self):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">        print(&quot;<\/span><span style=\"color: #EBCB8B\">\\n<\/span><span style=\"color: #A3BE8C\">on_RxTimeout&quot;)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">        print(self.get_irq_flags())<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">    def on_valid_header(self):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">        print(&quot;<\/span><span style=\"color: #EBCB8B\">\\n<\/span><span style=\"color: #A3BE8C\">on_ValidHeader&quot;)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">        print(self.get_irq_flags())<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">    def on_payload_crc_error(self):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">        print(&quot;<\/span><span style=\"color: #EBCB8B\">\\n<\/span><span style=\"color: #A3BE8C\">on_PayloadCrcError&quot;)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">        print(self.get_irq_flags())<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">    def on_fhss_change_channel(self):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">        print(&quot;<\/span><span style=\"color: #EBCB8B\">\\n<\/span><span style=\"color: #A3BE8C\">on_FhssChangeChannel&quot;)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">        print(self.get_irq_flags())<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">    def start(self):          <\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">        while True:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">            self.reset_ptr_rx()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">            self.set_mode(MODE.RXCONT) # Receiver mode<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">            while True:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">                pass;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">    def send(data):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">        data = [255, 255, 0, 0] + data + [0] <\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">        self.write_payload([data]) # Send DATA<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">        time.sleep(2)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">        self.reset_ptr_rx()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">        self.set_mode(MODE.RXCONT)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">lora = mylora(verbose=False)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">#args = parser.parse_args(lora) # configs in LoRaArgumentParser.py<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">#     Slow+long range  Bw = 125 kHz, Cr = 4\/8, Sf = 4096chips\/symbol, CRC on. 13 dBm<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">lora.set_pa_config(pa_select=1, max_power=21, output_power=15)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">lora.set_bw(BW.BW125)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">lora.set_coding_rate(CODING_RATE.CR4_8)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">lora.set_spreading_factor(12)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">lora.set_rx_crc(True)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">#lora.set_lna_gain(GAIN.G1)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">#lora.set_implicit_header_mode(False)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">lora.set_low_data_rate_optim(True)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">#  Medium Range  Defaults after init are 434.0MHz, Bw = 125 kHz, Cr = 4\/5, Sf = 128chips\/symbol, CRC on 13 dBm<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">#lora.set_pa_config(pa_select=1)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">assert(lora.get_agc_auto_on() == 1)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">try:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">    print(&quot;START&quot;)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">    lora.start()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">except KeyboardInterrupt:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">    sys.stdout.flush()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">    print(&quot;Exit&quot;)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">    sys.stderr.write(&quot;KeyboardInterrupt<\/span><span style=\"color: #EBCB8B\">\\n<\/span><span style=\"color: #A3BE8C\">&quot;)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">finally:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">    sys.stdout.flush()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">    print(&quot;Exit&quot;)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">    lora.set_mode(MODE.SLEEP)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A3BE8C\">BOARD.teardown()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">&quot;&quot;&quot;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">   <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">signal<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">signal<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">signal<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9FF\">SIGINT<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> signal_handler<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">def<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">process_events<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9\">log<\/span><span style=\"color: #81A1C1\">=False<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9\">lorasend<\/span><span style=\"color: #81A1C1\">=False<\/span><span style=\"color: #ECEFF4\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">global<\/span><span style=\"color: #D8DEE9FF\"> cps<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">global<\/span><span style=\"color: #D8DEE9FF\"> cpm<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    nowtime <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> time<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">time<\/span><span style=\"color: #ECEFF4\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    prune_before_time <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> nowtime <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\"> start_time_epoch <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">60.0<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">for<\/span><span style=\"color: #D8DEE9FF\"> pulse <\/span><span style=\"color: #81A1C1\">in<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">list<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">pulse_events<\/span><span style=\"color: #ECEFF4\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">pulse <\/span><span style=\"color: #81A1C1\">&lt;<\/span><span style=\"color: #D8DEE9FF\"> prune_before_time<\/span><span style=\"color: #ECEFF4\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            pulse_events<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">popleft<\/span><span style=\"color: #ECEFF4\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    cps <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">len<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">pulse_events<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #B48EAD\">60.0<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    cpm <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">len<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">pulse_events<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #88C0D0\">print<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">cpm<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">not<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #88C0D0\">int<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">time<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">time<\/span><span style=\"color: #ECEFF4\">())<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">%<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">60<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">and<\/span><span style=\"color: #D8DEE9FF\"> prune_before_time <\/span><span style=\"color: #81A1C1\">&gt;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0<\/span><span style=\"color: #ECEFF4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #616E88\"># log last minute cpm to db. wait at least 60 sec from start<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #616E88\"># to get steady state data.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #88C0D0\">print<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">last minute cpm:<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">str<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">cpm<\/span><span style=\"color: #ECEFF4\">))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">lorasend<\/span><span style=\"color: #ECEFF4\">):<\/span><span style=\"color: #D8DEE9FF\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            epoch_ms <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">int<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">time<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">time<\/span><span style=\"color: #ECEFF4\">()<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #B48EAD\">1000.0<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            buffer_data <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> struct<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">pack<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">&lt;Q<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> epoch_ms<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># pack epoch_ms into byte array little endian<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            buffer_data <\/span><span style=\"color: #81A1C1\">+=<\/span><span style=\"color: #D8DEE9FF\"> struct<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">pack<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">&lt;L<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> cpm<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># append cpm into byte array little endian<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #616E88\">#lora.send(buffer_data)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #88C0D0\">print<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">buffer_data<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">log<\/span><span style=\"color: #ECEFF4\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            sql <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">INSERT INTO data_cpm (timestamp_utc,count_per_minute,coordinates) VALUES(<\/span><span style=\"color: #EBCB8B\">%s<\/span><span style=\"color: #A3BE8C\">, <\/span><span style=\"color: #EBCB8B\">%s<\/span><span style=\"color: #A3BE8C\">, ST_PointFromWKB(ST_AsBinary(POINT(<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">str<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">lat<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">,<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">str<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">long<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">)), 4326))<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #D8DEE9\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            val <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #88C0D0\">str<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">datetime<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9FF\">datetime<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">now<\/span><span style=\"color: #ECEFF4\">()),<\/span><span style=\"color: #88C0D0\">str<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">cpm<\/span><span style=\"color: #ECEFF4\">))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            cur<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">execute<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">sql<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> val<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            conn<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">commit<\/span><span style=\"color: #ECEFF4\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    processing_delay <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> time<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">time<\/span><span style=\"color: #ECEFF4\">()<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\"> nowtime<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #88C0D0\">print<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">processing_delay<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    proc_delay_mul <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">int<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">processing_delay<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    time<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">sleep<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> proc_delay_mul <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\"> processing_delay<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #616E88\"># ensure isochronous sampling, add n skip seconds in case of the block taking a really long time...<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #616E88\"># asynchronous mariadb cursor should prevent this occurence.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">prune_before_time <\/span><span style=\"color: #81A1C1\">&gt;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0<\/span><span style=\"color: #ECEFF4\">):<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\"># 60 sec have elapsed<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #81A1C1\">return<\/span><span style=\"color: #D8DEE9FF\"> cpm<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">else<\/span><span style=\"color: #ECEFF4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #81A1C1\">return<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #B48EAD\">1<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #616E88\">#while process_pulses:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #616E88\">#    process_events()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #616E88\">#signal.pause()<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p><br><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Article updated the 20th of August 2025, reflecting the recent analysis of GPIO performance of Raspberry Pi in user space contexts and Python, vs kernel based contexts using GPIOd_* functions or MMIO, and the suitability of Linux Industrial IO subsystem for such endeavours.DUT pictures were added. When interfacing a Geiger-Muller device with a MCU or<\/p><\/div>\n<div class=\"blog-btn\"><a href=\"https:\/\/www.skynext.tech\/index.php\/2024\/08\/31\/geiger-muller-counter-interfacing-with-raspberry-pi\/\" class=\"home-blog-btn\">Read More<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_editorskit_title_hidden":false,"_editorskit_reading_time":0,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","pmpro_default_level":"","footnotes":""},"categories":[122],"tags":[],"class_list":["post-1216","post","type-post","status-publish","format-standard","hentry","category-metrology","pmpro-has-access"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v25.9 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Geiger-Muller counter interfacing with Raspberry Pi. - SKYNEXT Tech.<\/title>\n<meta name=\"description\" content=\"Geiger-Muller counter interfacing with Raspberry Pi accounting for dead time with calibration helper Python script.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.skynext.tech\/index.php\/2024\/08\/31\/geiger-muller-counter-interfacing-with-raspberry-pi\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Geiger-Muller counter interfacing with Raspberry Pi. - SKYNEXT Tech.\" \/>\n<meta property=\"og:description\" content=\"Geiger-Muller counter interfacing with Raspberry Pi accounting for dead time with calibration helper Python script.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.skynext.tech\/index.php\/2024\/08\/31\/geiger-muller-counter-interfacing-with-raspberry-pi\/\" \/>\n<meta property=\"og:site_name\" content=\"SKYNEXT Tech.\" \/>\n<meta property=\"article:published_time\" content=\"2024-08-31T14:10:02+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-08-20T13:23:45+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.skynext.tech\/wp-content\/uploads\/2024\/08\/GM_module_1_1_CAJOE.png\" \/>\n\t<meta property=\"og:image:width\" content=\"661\" \/>\n\t<meta property=\"og:image:height\" content=\"536\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"R.Verissimo\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"R.Verissimo\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"21 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.skynext.tech\/index.php\/2024\/08\/31\/geiger-muller-counter-interfacing-with-raspberry-pi\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.skynext.tech\/index.php\/2024\/08\/31\/geiger-muller-counter-interfacing-with-raspberry-pi\/\"},\"author\":{\"name\":\"R.Verissimo\",\"@id\":\"https:\/\/www.skynext.tech\/#\/schema\/person\/6b71040d3e4353a85583550901159cd8\"},\"headline\":\"Geiger-Muller counter interfacing with Raspberry Pi.\",\"datePublished\":\"2024-08-31T14:10:02+00:00\",\"dateModified\":\"2025-08-20T13:23:45+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.skynext.tech\/index.php\/2024\/08\/31\/geiger-muller-counter-interfacing-with-raspberry-pi\/\"},\"wordCount\":7868,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.skynext.tech\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.skynext.tech\/index.php\/2024\/08\/31\/geiger-muller-counter-interfacing-with-raspberry-pi\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.skynext.tech\/wp-content\/uploads\/2024\/08\/GM_module_1_1_CAJOE.png\",\"articleSection\":[\"Metrology\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.skynext.tech\/index.php\/2024\/08\/31\/geiger-muller-counter-interfacing-with-raspberry-pi\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.skynext.tech\/index.php\/2024\/08\/31\/geiger-muller-counter-interfacing-with-raspberry-pi\/\",\"url\":\"https:\/\/www.skynext.tech\/index.php\/2024\/08\/31\/geiger-muller-counter-interfacing-with-raspberry-pi\/\",\"name\":\"Geiger-Muller counter interfacing with Raspberry Pi. - SKYNEXT Tech.\",\"isPartOf\":{\"@id\":\"https:\/\/www.skynext.tech\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.skynext.tech\/index.php\/2024\/08\/31\/geiger-muller-counter-interfacing-with-raspberry-pi\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.skynext.tech\/index.php\/2024\/08\/31\/geiger-muller-counter-interfacing-with-raspberry-pi\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.skynext.tech\/wp-content\/uploads\/2024\/08\/GM_module_1_1_CAJOE.png\",\"datePublished\":\"2024-08-31T14:10:02+00:00\",\"dateModified\":\"2025-08-20T13:23:45+00:00\",\"description\":\"Geiger-Muller counter interfacing with Raspberry Pi accounting for dead time with calibration helper Python script.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.skynext.tech\/index.php\/2024\/08\/31\/geiger-muller-counter-interfacing-with-raspberry-pi\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.skynext.tech\/index.php\/2024\/08\/31\/geiger-muller-counter-interfacing-with-raspberry-pi\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.skynext.tech\/index.php\/2024\/08\/31\/geiger-muller-counter-interfacing-with-raspberry-pi\/#primaryimage\",\"url\":\"https:\/\/www.skynext.tech\/wp-content\/uploads\/2024\/08\/GM_module_1_1_CAJOE.png\",\"contentUrl\":\"https:\/\/www.skynext.tech\/wp-content\/uploads\/2024\/08\/GM_module_1_1_CAJOE.png\",\"width\":661,\"height\":536},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.skynext.tech\/index.php\/2024\/08\/31\/geiger-muller-counter-interfacing-with-raspberry-pi\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.skynext.tech\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Geiger-Muller counter interfacing with Raspberry Pi.\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.skynext.tech\/#website\",\"url\":\"https:\/\/www.skynext.tech\/\",\"name\":\"SKYNEXT Tech.\",\"description\":\"Power Electronics &amp; Metrology\",\"publisher\":{\"@id\":\"https:\/\/www.skynext.tech\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.skynext.tech\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.skynext.tech\/#organization\",\"name\":\"SKYNEXT Tech.\",\"alternateName\":\"DELIVERYSIMO EIRL\",\"url\":\"https:\/\/www.skynext.tech\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.skynext.tech\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.skynext.tech\/wp-content\/uploads\/2019\/09\/cropped-SKYNEXT_logo_square-2.png\",\"contentUrl\":\"https:\/\/www.skynext.tech\/wp-content\/uploads\/2019\/09\/cropped-SKYNEXT_logo_square-2.png\",\"width\":210,\"height\":210,\"caption\":\"SKYNEXT Tech.\"},\"image\":{\"@id\":\"https:\/\/www.skynext.tech\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.skynext.tech\/#\/schema\/person\/6b71040d3e4353a85583550901159cd8\",\"name\":\"R.Verissimo\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.skynext.tech\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/0bf345444b71baae1301e50a1a8cbeb98a5b7f41b85ffe9e1e6c2640ef23b528?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/0bf345444b71baae1301e50a1a8cbeb98a5b7f41b85ffe9e1e6c2640ef23b528?s=96&d=mm&r=g\",\"caption\":\"R.Verissimo\"},\"url\":\"https:\/\/www.skynext.tech\/index.php\/author\/wpadmin\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Geiger-Muller counter interfacing with Raspberry Pi. - SKYNEXT Tech.","description":"Geiger-Muller counter interfacing with Raspberry Pi accounting for dead time with calibration helper Python script.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.skynext.tech\/index.php\/2024\/08\/31\/geiger-muller-counter-interfacing-with-raspberry-pi\/","og_locale":"en_US","og_type":"article","og_title":"Geiger-Muller counter interfacing with Raspberry Pi. - SKYNEXT Tech.","og_description":"Geiger-Muller counter interfacing with Raspberry Pi accounting for dead time with calibration helper Python script.","og_url":"https:\/\/www.skynext.tech\/index.php\/2024\/08\/31\/geiger-muller-counter-interfacing-with-raspberry-pi\/","og_site_name":"SKYNEXT Tech.","article_published_time":"2024-08-31T14:10:02+00:00","article_modified_time":"2025-08-20T13:23:45+00:00","og_image":[{"width":661,"height":536,"url":"https:\/\/www.skynext.tech\/wp-content\/uploads\/2024\/08\/GM_module_1_1_CAJOE.png","type":"image\/png"}],"author":"R.Verissimo","twitter_card":"summary_large_image","twitter_misc":{"Written by":"R.Verissimo","Est. reading time":"21 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.skynext.tech\/index.php\/2024\/08\/31\/geiger-muller-counter-interfacing-with-raspberry-pi\/#article","isPartOf":{"@id":"https:\/\/www.skynext.tech\/index.php\/2024\/08\/31\/geiger-muller-counter-interfacing-with-raspberry-pi\/"},"author":{"name":"R.Verissimo","@id":"https:\/\/www.skynext.tech\/#\/schema\/person\/6b71040d3e4353a85583550901159cd8"},"headline":"Geiger-Muller counter interfacing with Raspberry Pi.","datePublished":"2024-08-31T14:10:02+00:00","dateModified":"2025-08-20T13:23:45+00:00","mainEntityOfPage":{"@id":"https:\/\/www.skynext.tech\/index.php\/2024\/08\/31\/geiger-muller-counter-interfacing-with-raspberry-pi\/"},"wordCount":7868,"commentCount":0,"publisher":{"@id":"https:\/\/www.skynext.tech\/#organization"},"image":{"@id":"https:\/\/www.skynext.tech\/index.php\/2024\/08\/31\/geiger-muller-counter-interfacing-with-raspberry-pi\/#primaryimage"},"thumbnailUrl":"https:\/\/www.skynext.tech\/wp-content\/uploads\/2024\/08\/GM_module_1_1_CAJOE.png","articleSection":["Metrology"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.skynext.tech\/index.php\/2024\/08\/31\/geiger-muller-counter-interfacing-with-raspberry-pi\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.skynext.tech\/index.php\/2024\/08\/31\/geiger-muller-counter-interfacing-with-raspberry-pi\/","url":"https:\/\/www.skynext.tech\/index.php\/2024\/08\/31\/geiger-muller-counter-interfacing-with-raspberry-pi\/","name":"Geiger-Muller counter interfacing with Raspberry Pi. - SKYNEXT Tech.","isPartOf":{"@id":"https:\/\/www.skynext.tech\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.skynext.tech\/index.php\/2024\/08\/31\/geiger-muller-counter-interfacing-with-raspberry-pi\/#primaryimage"},"image":{"@id":"https:\/\/www.skynext.tech\/index.php\/2024\/08\/31\/geiger-muller-counter-interfacing-with-raspberry-pi\/#primaryimage"},"thumbnailUrl":"https:\/\/www.skynext.tech\/wp-content\/uploads\/2024\/08\/GM_module_1_1_CAJOE.png","datePublished":"2024-08-31T14:10:02+00:00","dateModified":"2025-08-20T13:23:45+00:00","description":"Geiger-Muller counter interfacing with Raspberry Pi accounting for dead time with calibration helper Python script.","breadcrumb":{"@id":"https:\/\/www.skynext.tech\/index.php\/2024\/08\/31\/geiger-muller-counter-interfacing-with-raspberry-pi\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.skynext.tech\/index.php\/2024\/08\/31\/geiger-muller-counter-interfacing-with-raspberry-pi\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.skynext.tech\/index.php\/2024\/08\/31\/geiger-muller-counter-interfacing-with-raspberry-pi\/#primaryimage","url":"https:\/\/www.skynext.tech\/wp-content\/uploads\/2024\/08\/GM_module_1_1_CAJOE.png","contentUrl":"https:\/\/www.skynext.tech\/wp-content\/uploads\/2024\/08\/GM_module_1_1_CAJOE.png","width":661,"height":536},{"@type":"BreadcrumbList","@id":"https:\/\/www.skynext.tech\/index.php\/2024\/08\/31\/geiger-muller-counter-interfacing-with-raspberry-pi\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.skynext.tech\/"},{"@type":"ListItem","position":2,"name":"Geiger-Muller counter interfacing with Raspberry Pi."}]},{"@type":"WebSite","@id":"https:\/\/www.skynext.tech\/#website","url":"https:\/\/www.skynext.tech\/","name":"SKYNEXT Tech.","description":"Power Electronics &amp; Metrology","publisher":{"@id":"https:\/\/www.skynext.tech\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.skynext.tech\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.skynext.tech\/#organization","name":"SKYNEXT Tech.","alternateName":"DELIVERYSIMO EIRL","url":"https:\/\/www.skynext.tech\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.skynext.tech\/#\/schema\/logo\/image\/","url":"https:\/\/www.skynext.tech\/wp-content\/uploads\/2019\/09\/cropped-SKYNEXT_logo_square-2.png","contentUrl":"https:\/\/www.skynext.tech\/wp-content\/uploads\/2019\/09\/cropped-SKYNEXT_logo_square-2.png","width":210,"height":210,"caption":"SKYNEXT Tech."},"image":{"@id":"https:\/\/www.skynext.tech\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.skynext.tech\/#\/schema\/person\/6b71040d3e4353a85583550901159cd8","name":"R.Verissimo","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.skynext.tech\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/0bf345444b71baae1301e50a1a8cbeb98a5b7f41b85ffe9e1e6c2640ef23b528?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/0bf345444b71baae1301e50a1a8cbeb98a5b7f41b85ffe9e1e6c2640ef23b528?s=96&d=mm&r=g","caption":"R.Verissimo"},"url":"https:\/\/www.skynext.tech\/index.php\/author\/wpadmin\/"}]}},"_links":{"self":[{"href":"https:\/\/www.skynext.tech\/index.php\/wp-json\/wp\/v2\/posts\/1216","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.skynext.tech\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.skynext.tech\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.skynext.tech\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.skynext.tech\/index.php\/wp-json\/wp\/v2\/comments?post=1216"}],"version-history":[{"count":95,"href":"https:\/\/www.skynext.tech\/index.php\/wp-json\/wp\/v2\/posts\/1216\/revisions"}],"predecessor-version":[{"id":1569,"href":"https:\/\/www.skynext.tech\/index.php\/wp-json\/wp\/v2\/posts\/1216\/revisions\/1569"}],"wp:attachment":[{"href":"https:\/\/www.skynext.tech\/index.php\/wp-json\/wp\/v2\/media?parent=1216"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.skynext.tech\/index.php\/wp-json\/wp\/v2\/categories?post=1216"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.skynext.tech\/index.php\/wp-json\/wp\/v2\/tags?post=1216"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}