Close Menu
    Facebook LinkedIn YouTube WhatsApp X (Twitter) Pinterest
    Trending
    • 1000xResist Studio’s Next Indie Game Asks: Can You Convince an AI It Isn’t Human?
    • Efficient hybrid minivan delivers MPG
    • How Can Astronauts Tell How Fast They’re Going?
    • A look at the AI nonprofit METR, whose time-horizon metrics are used by AI researchers and Wall Street investors to track the rapid development of AI systems (Kevin Roose/New York Times)
    • Double Dazzle: This Weekend, There Are 2 Meteor Showers in the Night Sky
    • asexual fish defy extinction with gene repair
    • The ‘Lonely Runner’ Problem Only Appears Simple
    • Binance and Bitget to probe a rally in RaveDAO’s RAVE token, which surged 4,500% in a week, after ZachXBT alleged RAVE insiders engineered a large short squeeze (Francisco Rodrigues/CoinDesk)
    Facebook LinkedIn WhatsApp
    Times FeaturedTimes Featured
    Sunday, April 19
    • Home
    • Founders
    • Startups
    • Technology
    • Profiles
    • Entrepreneurs
    • Leaders
    • Students
    • VC Funds
    • More
      • AI
      • Robotics
      • Industries
      • Global
    Times FeaturedTimes Featured
    Home»Artificial Intelligence»Exploratory Data Analysis: Gamma Spectroscopy in Python (Part 3)
    Artificial Intelligence

    Exploratory Data Analysis: Gamma Spectroscopy in Python (Part 3)

    Editor Times FeaturedBy Editor Times FeaturedAugust 5, 2025No Comments11 Mins Read
    Facebook Twitter Pinterest Telegram LinkedIn Tumblr WhatsApp Email
    Share
    Facebook Twitter LinkedIn Pinterest Telegram Email WhatsApp Copy Link


    objects round us will be barely radioactive. Americium in smoke detectors, radium in some classic watches, or uranium in classic glass; a full record will be lengthy. Largely, these objects are protected and can’t trigger a well being threat. Additionally it is attention-grabbing to establish them and examine the matter on the atomic degree. And we will do that utilizing a radiation detector. In the first part, I did an exploratory information evaluation of the gamma spectroscopy information. Within the second part, I created a machine studying mannequin for detecting radioactive isotopes. That is the final third half, and it’s time so as to add a created mannequin to the actual app!

    On this story, I’ll take a look at two approaches:

    • I’ll create a public Streamlit app that can be hosted at no cost on Streamlit Cloud (the app hyperlink is added to the top of the article).
    • As a extra versatile and common resolution, I’ll create a Python HTMX-based app that may talk with actual {hardware} and make predictions in actual time.

    In the identical means as within the earlier half, I’ll use a Radiacode scintillation detector to get the information (disclaimer: the system used on this take a look at was supplied by the producer; I don’t get any business revenue from their gross sales, and I didn’t get any editorial enter about all of the exams). Readers who don’t have a Radiacode {hardware} will have the ability to take a look at the app and the mannequin utilizing information accessible on Kaggle.

    Let’s get began!

    1. Isotopes Classification Mannequin

    This mannequin was described within the previous part. It’s based mostly on XGBoost, and I educated the mannequin utilizing completely different radioactive samples. I used samples that may be legally bought, like classic uranium glass or outdated watches with radium dials made within the Fifties. As talked about earlier than, I additionally used a Radiacode scintillation detector, which permits me to get the gamma spectrum of the thing. Solely 10-20 years in the past, these kinds of detectors have been accessible solely in massive labs; in the present day, they are often bought for the value of a mid-range smartphone.

    The mannequin comprises three parts:

    • The XGBoost-based mannequin itself.
    • An inventory of radioactive isotopes (like Lead-214 or Actinium-228), on which the mannequin was educated. The Radiacode scintillation detector returns 1024 spectrum values, and 23 of them have been used for the mannequin.
    • A label encoder to transform record indexes into human-readable names.

    Let’s wrap all this right into a single Python class:

    from xgboost import XGBClassifier
    from sklearn.preprocessing import LabelEncoder
    
    
    class IsotopesClassificationModel:
        """ Gamma Spectrum Classification Mannequin """
    
        def __init__(self):
            """ Load fashions """
            path = self._get_models_path()
            self._classifier = self._load_model(path + "/XGBClassifier.json")
            self._isotopes = self._load_isotopes(path + "/isotopes.json")
            self._labels_encoder = self._load_labels_encoder(path + "/LabelEncoder.npy")
    
        def predict(self, spectrum: Spectrum) -> str:
            """ Predict the isotope """
            options = SpectrumPreprocessing.convert_to_features(
                spectrum, self._isotopes
            )
            preds = self._classifier.predict([features])
            preds = self._labels_encoder.inverse_transform(preds)
            return preds[0]
    
        @staticmethod
        def _load_model(filename: str) -> XGBClassifier:
            """ Load mannequin from file """
            bst = XGBClassifier()
            bst.load_model(filename)
            return bst
    
        @staticmethod
        def _load_isotopes(filename: str) -> Record:
            with open(filename, "r") as f_in:
                return json.load(f_in)
    
        @staticmethod
        def _load_labels_encoder(filename: str) -> LabelEncoder:
            le = LabelEncoder()
            le.classes_ = np.load(filename)
            return le
    
        @staticmethod
        def _get_models_path() -> str:
            """ Get path to fashions. Mannequin information are saved in 
                'fashions/V1/' folder """
            parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
            return parent_dir + f"/fashions/{IsotopesClassificationModel.VERSION}"

    A Spectrum class comprises the spectrum information we get from a radiation detector:

    @dataclass
    class Spectrum:
        """ Radiation spectrum information """
    
        length: datetime.timedelta
        a0: float
        a1: float
        a2: float
        counts: record[int]

    Right here, counts is a gamma spectrum, which is represented by a listing of 1024 channel values. Spectrum information will be exported utilizing the official Radiacode Android app or retrieved straight from a tool utilizing a radiacode Python library.

    To load the spectrum into the mannequin, I created a SpectrumPreprocessing class:

    class SpectrumPreprocessing:
        """ Gamma Spectrum Preprocessing """
    
        @staticmethod
        def convert_to_features(spectrum: Spectrum, isotopes: Record) -> np.array:
            """ Convert the spectrum to the record of options for prediction """
            sp_norm = SpectrumPreprocessing._normalize(spectrum)
            energies = [energy for _, energy in isotopes]
            channels = [SpectrumPreprocessing.energy_to_channel(spectrum, energy) for energy in energies]
            return np.array([sp_norm.counts[ch] for ch in channels])
    
        @staticmethod 
        def load_from_xml_file(file_path: str) -> Spectrum:
            """ Load spectrum from a Radiacode Android app file """

    Right here, I skip some code blocks that have been already printed within the previous part. Extracting options from the gamma spectrum was additionally defined there, and I extremely suggest studying that half first.

    Now, let’s take a look at the mannequin! I took a Radiacode detector and picked up a gamma spectrum inside 10 minutes:

    Radiacode radiation detector, Picture by writer

    This Chinese language pendant was marketed as “ion-generated,” and it’s barely radioactive. Its gamma spectrum, collected within the official Radiacode Android app, appears like this:

    Screenshot by writer

    After ready for ~10 minutes, I exported the spectrum into an XML file. Now, we will run the mannequin:

    from spectrum import SpectrumPreprocessing
    from ml_models import IsotopesClassificationModel
    
    sp = SpectrumPreprocessing.load_from_file("spectrum.xml")
    mannequin = IsotopesClassificationModel()
    outcome = mannequin.predict(sp)
    print(outcome)
    
    #> Thorium

    As we will see, the mannequin works effectively. We will examine the peaks with spectra of identified isotopes (for instance, here or here) and ensure that the spectrum belongs to thorium.

    2. Streamlit

    The mannequin works; nevertheless, we stay within the XXI century, and nearly no one will run the console app to get the outcomes. As a substitute, we will make the app accessible on-line, so all Radiacode customers will have the ability to run it.

    There are a lot of Python frameworks for making browser-based apps, and Streamlit might be the most well-liked within the information science neighborhood. And what’s vital for us, a Streamlit Community Cloud platform permits everybody to publish their apps fully at no cost. To do that, let’s make the app first.

    2.1 Streamlit App

    A Streamlit framework is comparatively simple to make use of, no less than if a standard-looking app is sweet for us. Personally, I’m not a fan of this strategy. These frameworks disguise all low-level implementation particulars from customers. It’s easy to make a prototype, however the UI logic can be tightly coupled with a really area of interest framework and can’t be reused anyplace else. Doing every little thing non-standard, which isn’t supported by the framework, will be nearly unattainable or onerous to implement with out digging into tons of abstractions and pages of code. Nevertheless, in our case, the prototype is all we’d like.

    Normally, a Streamlit code is easy, and we simply want to explain the logical hierarchy of our web page:

    import streamlit as st
    import logging
    logger = logging.getLogger(__name__)
    
    
    def is_xml_valid(xml_data: str) -> bool:
        """ Test if the XML has legitimate measurement and information """
        return len(xml_data) < 65535 and xml_data.startswith(" Non-compulsory[Spectrum]:
        """ Load spectrum from the StringIO stream """
        xml_data = stringio.learn()
        if is_xml_valid(xml_data):
            return SpectrumPreprocessing.load_from_xml(xml_data)
        return None
    
    def predominant():
        """ Principal app """
        st.set_page_config(page_title="Gamma Spectrum")
        st.title("Radiacode Spectrum Detection")
        st.textual content(
            "Export the spectrum to XML utilizing the Radiacode app, and "
            "add it to see the outcomes."
        )
    
        # File Add
        uploaded_file = st.file_uploader(
            "Select the XML file", sort="xml", key="uploader",
        )
        if uploaded_file isn't None:
            stringio = StringIO(uploaded_file.getvalue().decode("utf-8"))
            if sp := get_spectrum(stringio):
                # Prediction
                mannequin = IsotopesClassificationModel()
                outcome = mannequin.predict(sp)
                logger.data(f"Spectrum prediction: {outcome}")
    
                # Present outcome
                st.success(f"Prediction Outcome: {outcome}")
                # Draw
                fig = get_spectrum_barchart(sp)
                st.pyplot(fig)
    
    
    if __name__ == "__main__":
        logger.setLevel(logging.INFO)
        predominant()

    As we will see, the complete app requires a minimal quantity of Python code. Streamlit will render all HTML for us, with title, file add, and outcomes. As a bonus, I can even show a spectrum utilizing Matplotlib:

    def get_spectrum_barchart(sp: Spectrum) -> plt.Determine:
        """ Get Matplotlib's barchart """
        counts = SpectrumPreprocessing.get_counts(sp)
        power = [
           SpectrumPreprocessing.channel_to_energy(sp, x) for x in range(len(counts))
        ]
    
        fig, ax = plt.subplots(figsize=(9, 6))
        ax.spines["top"].set_color("lightgray")
        ax.spines["right"].set_color("lightgray")
        # Bars
        ax.bar(power, counts, width=3.0, label="Counts")
        # X values
        ticks_x = [SpectrumPreprocessing.channel_to_energy(sp, ch) for ch in range(0, len(counts), len(counts) // 20)]
        labels_x = [f"{int(ch)}" for ch in ticks_x]
        ax.set_xticks(ticks_x, labels=labels_x, rotation=45)
        ax.set_xlim(power[0], power[-1])
        ax.set_ylim(0, None)
        ax.set_title("Gamma spectrum")
        ax.set_xlabel("Vitality, keV")
        ax.set_ylabel("Counts")
        return fig

    Now we will run the app domestically:

    streamlit run st-app.py

    After that, our app is absolutely operational and will be examined in a browser:

    Screenshot by writer

    As talked about earlier than, I’m not a fan of very high-level frameworks and like to have a greater understanding of how issues work “below the hood.” Nevertheless, contemplating that I spent solely about 100 strains of code to make a totally useful internet app, I can’t complain – for prototyping, it really works effectively.

    2.2 Streamlit Neighborhood Cloud

    When the app is examined domestically, it’s time to make it public! A Streamlit Cloud is a free service, and clearly, it has a number of limitations:

    • The app runs in a Docker-like container. Your GitHub account have to be linked to Streamlit. When the container begins, it pulls your code from GitHub and runs it.
    • On the time of scripting this textual content, container sources are restricted to 2 cores and as much as 2,7 GB of RAM. It might be too constrained to run a 70B measurement LLM, however for a small XGBoost mannequin, it’s greater than sufficient.
    • Streamlit doesn’t present any everlasting storage. After shutdown or restart, all logs and non permanent information can be misplaced (you should use API secrets and techniques and hook up with another cloud storage out of your Python code if wanted).
    • After a interval of inactivity (about half-hour), the container can be stopped, and all non permanent information can even be misplaced. If somebody opens the app hyperlink, it should run once more.

    As readers can guess, an inactive app prices Streamlit nearly nothing as a result of it shops solely a small configuration file. And it’s a good resolution for a free service – it permits us to publish the app with none prices and provides individuals a hyperlink to run it.

    To publish the app in Streamlit, we have to carry out three easy steps.

    First, we have to commit our Python app to GitHub. A necessities.txt file can be obligatory. Streamlit container makes use of it to put in required Python dependencies. In my case, it appears like this:

    xgboost==3.0.2
    scikit-learn==1.6.1
    numpy==1.26.4
    streamlit==1.47.0
    pillow==11.1.0
    matplotlib==3.10.3
    xmltodict==0.14.2

    Server settings will be modified utilizing a .streamlit/config.toml file. In my case, I restricted the uploaded file measurement to 1 MB as a result of all spectra information are smaller:

    [server]
    # Max measurement, in megabytes, for information uploaded with the file_uploader.
    # Default: 200
    maxUploadSize = 1

    Second, we have to log in to share.streamlit.io utilizing a GitHub account and provides permission to entry the supply code.

    Lastly, we will create a brand new Streamlit mission. Within the mission settings, we will additionally choose the specified URL and setting:

    Picture by writer

    If every little thing was achieved accurately, we will see our app operating:

    Picture by writer

    At this second, customers worldwide may entry our app! In my case, I chosen a gammaspectrumdetection title, and the app is offered utilizing this URL.

    3. FastAPI + HTMX App

    As readers can see, Streamlit is a pleasant resolution for a easy prototype. Nevertheless, within the case of the radiation detector, I want to see information coming from actual Radiacode {hardware}. This might be unattainable to do in Streamlit; this library simply was not designed for that. As a substitute, I’ll use a number of production-grade frameworks:

    • An HTMX framework permits us to make a totally useful internet interface.
    • FastAPI will run the server.
    • The ML mannequin will course of the information retrieved in real-time from a radiation detector utilizing a Radiacode library.

    As talked about earlier than, these readers who don’t have a Radiacode {hardware} will have the ability to replay the information utilizing uncooked log information, saved from an actual system. A hyperlink to the app and all information is offered on the finish of the article.

    Let’s get into it!

    3.1 HTML/HTMX

    The app is linked to a Radiacode detector, and I made a decision to point out a connection standing, radiation degree, and a spectrum graph on the web page. On the backside, a spectrum assortment time and an ML mannequin prediction can be displayed.

    An index.html file for this structure appears like this:

    
    
        
        Gamma Spectrum & Monitoring
        
        
    
        

    Assortment Time:
    n/a

    Prediction:
    n/a



    Source link

    Share. Facebook Twitter Pinterest LinkedIn Tumblr Email
    Editor Times Featured
    • Website

    Related Posts

    AI Agents Need Their Own Desk, and Git Worktrees Give Them One

    April 18, 2026

    Your RAG System Retrieves the Right Data — But Still Produces Wrong Answers. Here’s Why (and How to Fix It).

    April 18, 2026

    Europe Warns of a Next-Gen Cyber Threat

    April 18, 2026

    How to Learn Python for Data Science Fast in 2026 (Without Wasting Time)

    April 18, 2026

    A Practical Guide to Memory for Autonomous LLM Agents

    April 17, 2026

    You Don’t Need Many Labels to Learn

    April 17, 2026

    Comments are closed.

    Editors Picks

    1000xResist Studio’s Next Indie Game Asks: Can You Convince an AI It Isn’t Human?

    April 19, 2026

    Efficient hybrid minivan delivers MPG

    April 19, 2026

    How Can Astronauts Tell How Fast They’re Going?

    April 19, 2026

    A look at the AI nonprofit METR, whose time-horizon metrics are used by AI researchers and Wall Street investors to track the rapid development of AI systems (Kevin Roose/New York Times)

    April 19, 2026
    Categories
    • Founders
    • Startups
    • Technology
    • Profiles
    • Entrepreneurs
    • Leaders
    • Students
    • VC Funds
    About Us
    About Us

    Welcome to Times Featured, an AI-driven entrepreneurship growth engine that is transforming the future of work, bridging the digital divide and encouraging younger community inclusion in the 4th Industrial Revolution, and nurturing new market leaders.

    Empowering the growth of profiles, leaders, entrepreneurs businesses, and startups on international landscape.

    Asia-Middle East-Europe-North America-Australia-Africa

    Facebook LinkedIn WhatsApp
    Featured Picks

    Motorcycle helmet visor instantly tints for sun glare

    February 13, 2026

    Coway Airmega 50 Review: Effective and Affordable (2025)

    July 20, 2025

    Top global AI leaders to gather in Valencia for the 7th edition of VDS

    September 30, 2024
    Categories
    • Founders
    • Startups
    • Technology
    • Profiles
    • Entrepreneurs
    • Leaders
    • Students
    • VC Funds
    Copyright © 2024 Timesfeatured.com IP Limited. All Rights.
    • Privacy Policy
    • Disclaimer
    • Terms and Conditions
    • About us
    • Contact us

    Type above and press Enter to search. Press Esc to cancel.