{"id":7510,"date":"2026-05-17T10:40:57","date_gmt":"2026-05-17T10:40:57","guid":{"rendered":"https:\/\/kellerbits.net\/wordpress\/?p=7510"},"modified":"2026-05-17T10:41:00","modified_gmt":"2026-05-17T10:41:00","slug":"building-a-desktop-pfas-screening-tool-with-python-and-rdkit","status":"publish","type":"post","link":"https:\/\/kellerbits.net\/wordpress\/?p=7510","title":{"rendered":"Building a Desktop PFAS Screening Tool with Python and RDKit"},"content":{"rendered":"\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Abstract<\/h2>\n\n\n\n<p><em>Per- and polyfluoroalkyl substances, commonly known as PFAS, are a group of thousands of synthetic chemicals manufactured since the 1940s [1, 2]. Their carbon-fluorine bonds, among the strongest single bonds in organic chemistry, with a bond dissociation energy of approximately 485 kJ\/mol [3], make them exceptionally resistant to heat, water, and oil, earning them the nickname &#8220;forever chemicals&#8221;: once released into the environment, they persist for decades or longer [4]. Regulators worldwide are tightening controls, and anyone working with fluorinated compounds needs reliable tools to determine whether a substance falls under the evolving PFAS definitions.<\/em><\/p>\n\n\n\n<p><em>This is a perfect setup for my latest coding project, building a PFAS Screening Tool that is easy to use and can screen a list of substances if they contain PFAS and if so, which kind of PFAS. This article describes the new desktop screening tool built in Python that classifies molecules as EU &amp; OECD PFAS, OECD-only PFAS, or not PFAS \u2014 applicable for entire inventories in batch mode, with CAS number resolution and embedded structure reports.<\/em><\/p>\n\n\n\n<p><strong>Why Two PFAS Definitions?<\/strong><\/p>\n\n\n\n<p>Two major regulatory frameworks define what counts as PFAS.<\/p>\n\n\n\n<p>The OECD 2021 revised definition [5] classifies a substance as PFAS if it contains at least one fully fluorinated methyl (CF<sub>3<\/sub>) or methylene (CF<sub>2<\/sub>) carbon atom. &#8220;Fully fluorinated&#8221; means the carbon is sp<sup>3<\/sup>-hybridised and carries no hydrogen, chlorine, bromine, or iodine.<\/p>\n\n\n\n<p>The ECHA restriction proposal [6] adopts the same structural criterion but adds exclusions for isolated, degradable moieties. A CF<sub>3<\/sub> group bonded to oxygen or nitrogen (CF<sub>3<\/sub>-OR or CF<sub>3<\/sub>-NRR&#8217;), or a CF<sub>2<\/sub> group flanked on both sides by {O, N, S} atoms, may qualify as OECD PFAS but not EU PFAS, provided the R groups are non-fluorinated. The distinction matters for regulatory compliance, product registration, and supply chain management.<\/p>\n\n\n\n<p><strong>The Classification Engine<\/strong><\/p>\n\n\n\n<p>At the heart of the tool is the classification engine, implemented as Section 1 of the single-file application <code>pfas_screening_app.py<\/code>. It uses a single external dependency: RDKit [7], the open-source cheminformatics toolkit. It accepts a SMILES string and returns a classification via atom-level molecular inspection, iterating through every atom and asking:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Is this carbon sp<sup>3<\/sup>-hybridised (saturated)?<\/li>\n\n\n\n<li>Does it carry zero hydrogen atoms?<\/li>\n\n\n\n<li>Does it have at least two fluorine neighbours?<\/li>\n\n\n\n<li>Are any neighbours hydrogen, chlorine, bromine, or iodine?<\/li>\n<\/ul>\n\n\n\n<p>A carbon passing all checks is a fully fluorinated carbon. If the molecule contains at least one, it is OECD PFAS.<\/p>\n\n\n\n<p>The EU layer is more nuanced. Every fully fluorinated carbon is evaluated individually: the EU exclusion applies only when each one independently qualifies. A CF<sub>3<\/sub> group qualifies if its non-fluorine neighbour is O or N and the attached R group contains no sp<sup>3<\/sup> C-F bonds and no sp<sup>2<\/sup> carbons bearing two or more fluorines. Aromatic rings are unconditionally accepted as R, per the EU definition&#8217;s explicit inclusion of &#8220;aromatic groups&#8221; [6]. For CF<sub>2<\/sub>, both flanking non-fluorine neighbours must be heteroatoms (O, N, or S); direct carbon neighbours do not qualify.<\/p>\n\n\n\n<p>For molecules with multiple fully fluorinated carbons, such as CF<sub>3<\/sub>-O-aryl-CF<sub>2<\/sub>-O-CH<sub>3<\/sub>, a breadth-first walk with a sibling-shielding test determines whether each carbon&#8217;s neighbours should be evaluated independently or together. This prevents both false exemptions and false positives on complex multi-center fluorinated scaffolds, including fluorinated agrochemicals and pharmaceutical intermediates.<\/p>\n\n\n\n<p>This atom-by-atom approach directly implements the regulatory text. The hybridisation check correctly excludes sp<sup>2<\/sup> carbons: tetrafluoroethylene (the Teflon monomer) has four fluorines but both carbons are sp<sup>2<\/sup>-hybridised, so it is correctly classified as not PFAS under the OECD definition [5].<\/p>\n\n\n\n<p><strong>CAS Number Resolution<\/strong><\/p>\n\n\n\n<p>The tool also accepts CAS numbers, resolved to canonical SMILES via the CAS lookup engine (Section 3 of <code>pfas_screening_app.py<\/code>), which queries PubChem [8] as its primary source and falls back to the NCI CACTUS resolver if PubChem cannot find an entry. Each lookup uses a single REST request; transient network errors on PubChem trigger up to three retry attempts with exponential backoff. Genuine not-found responses skip retrying and proceed immediately to the CACTUS fallback. The module also handles corporate proxy environments by falling back to an unverified SSL context if needed.<\/p>\n\n\n\n<p><strong>The Batch GUI<\/strong><\/p>\n\n\n\n<p>The batch GUI (<code>PFAS_BatchScreening<\/code>, Section 4 of <code>pfas_screening_app.py<\/code>) handles screening of entire inventories. The user selects an input file \u2014 either a plain text, CSV, SMI, or Excel file \u2014 and clicks Run Screening. Results populate a scrollable list, colour-coded pink (EU &amp; OECD PFAS), blue (OECD-only), neutral (non-PFAS), or red (error). Selecting any entry shows the full classification and a rendered 2D molecular structure.<\/p>\n\n\n\n<p>Input type is selected via radio buttons: Auto-detect (the default), SMILES, or CAS numbers. In auto-detect mode, the tool examines the first ten entries against a CAS regex pattern to choose the appropriate pipeline. Excel files receive additional handling: columns named SMILES, CAS, and ID\/NAME\/IDENTIFIER are detected automatically. When both SMILES and CAS columns are present, the GUI enters dual mode \u2014 rows with SMILES are screened directly, while CAS-only rows are queued for PubChem resolution.<\/p>\n\n\n\n<p>Processing is non-blocking throughout. SMILES classification uses tkinter&#8217;s <code>after()<\/code> method, one molecule per event-loop cycle. CAS-only mode paces lookups at 800 ms intervals to respect PubChem&#8217;s rate limit. In dual mode, CAS resolution runs in a background thread; results are pushed to a thread-safe queue and polled by the main thread every 300 ms, so the interface stays responsive as results arrive.<\/p>\n\n\n\n<p>The Create Report button generates an Excel file with embedded 2D structure images. For Excel input, all original columns are preserved alongside SMILES, Classification, and the structure image. For text\/CSV\/SMI input, the report contains ID, optionally CAS, SMILES, Classification, and the structure image. Temporary PNG files are cleaned up after the report is written.<\/p>\n\n\n\n<p><strong>Design Decisions Worth Noting<\/strong><\/p>\n\n\n\n<p><em>Single-file deployment.<\/em> All logic \u2014 the classification engine, tooltip helper, CAS lookup, and GUI \u2014 is consolidated into <code>pfas_screening_app.py<\/code>. There are no runtime imports from sibling modules. The file can be bundled into a standalone Windows executable using PyInstaller (<code>pyinstaller pfas_screening_app.spec<\/code>) without any packaging adjustments.<\/p>\n\n\n\n<p><em>Per-atom EU exemption evaluation.<\/em> Each fully fluorinated carbon is assessed independently against the EU exemption criteria [6]. This faithfully implements the regulatory text and correctly handles complex scaffolds that a simple count-based rule would misclassify.<\/p>\n\n\n\n<p><em>Conservative CF<sub>2<\/sub> flanking rule.<\/em> Only heteroatom flanking groups (O, N, S) qualify for the CF<sub>2<\/sub> exemption \u2014 carbon neighbours do not. Ph-CF<sub>2<\/sub>-Ph is therefore EU PFAS even though both flanking groups are sp<sup>2<\/sup>. This avoids underclassifying diaryl-CF<sub>2<\/sub> compounds that lack the degradable character the EU exclusion is intended to capture.<\/p>\n\n\n\n<p><em>Non-blocking architecture.<\/em> Single-mode CAS resolution and SMILES classification both use the event loop. Dual-mode CAS resolution offloads network I\/O to a background thread with queue-based polling, so slow PubChem responses for one entry do not block display of results already available.<\/p>\n\n\n\n<p><strong>Testing and Validation<\/strong><\/p>\n\n\n\n<p>The classification engine includes 23 built-in test cases covering: CF<sub>3<\/sub> bonded to sp<sup>3<\/sup> carbon (EU &amp; OECD PFAS); CF<sub>3<\/sub>-O-CH<sub>3<\/sub> (OECD-only); CF<sub>3<\/sub> with Br or Cl (not PFAS) [5]; CF<sub>3<\/sub>-O-CF<sub>2<\/sub>-CF<sub>3<\/sub> (EU &amp; OECD, R carries CF<sub>2<\/sub>); CF<sub>3<\/sub>-O-CHF<sub>2<\/sub> (EU &amp; OECD); CF<sub>3<\/sub>-O-phenyl and CF<sub>3<\/sub>-OH (both OECD-only); Ph-CF<sub>2<\/sub>-Ph (EU &amp; OECD, flanking C atoms); CH<sub>3<\/sub>-O-CF<sub>2<\/sub>-O-CH<sub>3<\/sub> (OECD-only); CF<sub>3<\/sub>-O-CF<sub>2<\/sub>-O-CH<sub>3 <\/sub>(EU &amp; OECD); complex fluorinated agrochemical scaffolds with multiple CF<sub>3<\/sub>-O-aryl and CF<sub>2<\/sub>-O-aryl groups (OECD-only, every FF carbon individually exempt [6]); and multi-centre fluorinated chains (EU &amp; OECD PFAS). These can be run by executing the standalone classification engine section directly.<\/p>\n\n\n\n<p><strong>Looking Ahead<\/strong><\/p>\n\n\n\n<p>For desktop and enterprise use, the tool correctly implements both the OECD 2021 [5] and EU ECHA [6] PFAS definitions via atom-level inspection, supports SMILES and CAS input through a responsive non-blocking GUI, handles Excel inventories with mixed SMILES and CAS columns, and produces structured Excel reports with embedded structures. The consolidated single-file architecture makes it straightforward to deploy as a standalone Windows executable. For teams managing chemical inventories under tightening regulations, it provides a fast, transparent, and auditable first screen.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Try it yourself in Python<\/h2>\n\n\n\n<p>Download the PFAS Screening Tool Python script from its Bitbucket repository here [9]: <a href=\"https:\/\/bitbucket.org\/nomapps\/pfas_screening_tool\">PFAS Screening Tool<\/a><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Prerequisites<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">Python Packages<\/h4>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Package<\/th><th class=\"has-text-align-left\" data-align=\"left\">Purpose<\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-left\" data-align=\"left\"><code>rdkit<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">Core cheminformatics \u2014 SMILES parsing and molecular inspection<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\"><code>Pillow<\/code>&nbsp;(<code>PIL<\/code>)<\/td><td class=\"has-text-align-left\" data-align=\"left\">Loading rendered molecule images into the GUI<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\"><code>pandas<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">Reading Excel input files in batch mode<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\"><code>openpyxl<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">Excel report generation with embedded structure images<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\"><code>XlsxWriter<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">Excel report generation in single-molecule mode<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\">Standard Library (no install needed)<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>tkinter<\/code>&nbsp;\u2014 GUI framework, ships with most Python distributions<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">Installation<\/h4>\n\n\n\n<p>There is no&nbsp;<code>requirements.txt<\/code>, so install manually:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>pip install rdkit Pillow pandas openpyxl XlsxWriter<\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><strong>Note:<\/strong>&nbsp;<code>rdkit<\/code>&nbsp;is best installed via conda if you run into issues with pip:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>conda install -c conda-forge rdkit<\/code><\/pre>\n<\/blockquote>\n\n\n\n<h4 class=\"wp-block-heading\">Other Requirements<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Python 3.x<\/strong>&nbsp;(RDKit requires Python 3)<\/li>\n\n\n\n<li><strong>Internet access<\/strong>&nbsp;\u2014 only needed in batch mode when resolving CAS numbers via the PubChem API<\/li>\n\n\n\n<li><strong>Corporate proxy \/ SSL:<\/strong>&nbsp;if behind a corporate firewall,&nbsp;<code>pubchem_lookup.py<\/code>&nbsp;attempts to handle SSL certificate issues automatically via&nbsp;<code>create_ssl_context()<\/code><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Performing the PFAS Screening<\/h3>\n\n\n\n<p>When the script is executed, you will see the following GUI:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"568\" src=\"https:\/\/i0.wp.com\/kellerbits.net\/wordpress\/wp-content\/uploads\/2026\/05\/PFAS_ST_pic1.jpg?resize=750%2C568&#038;ssl=1\" alt=\"\" class=\"wp-image-7556\" srcset=\"https:\/\/i0.wp.com\/kellerbits.net\/wordpress\/wp-content\/uploads\/2026\/05\/PFAS_ST_pic1.jpg?resize=1024%2C776&amp;ssl=1 1024w, https:\/\/i0.wp.com\/kellerbits.net\/wordpress\/wp-content\/uploads\/2026\/05\/PFAS_ST_pic1.jpg?resize=300%2C227&amp;ssl=1 300w, https:\/\/i0.wp.com\/kellerbits.net\/wordpress\/wp-content\/uploads\/2026\/05\/PFAS_ST_pic1.jpg?resize=768%2C582&amp;ssl=1 768w, https:\/\/i0.wp.com\/kellerbits.net\/wordpress\/wp-content\/uploads\/2026\/05\/PFAS_ST_pic1.jpg?resize=1536%2C1164&amp;ssl=1 1536w, https:\/\/i0.wp.com\/kellerbits.net\/wordpress\/wp-content\/uploads\/2026\/05\/PFAS_ST_pic1.jpg?w=1648&amp;ssl=1 1648w\" sizes=\"auto, (max-width: 750px) 100vw, 750px\" \/><\/figure>\n\n\n\n<p><em>Picture 1: GUI of the PFAS Screening Script<\/em><\/p>\n\n\n\n<p>Then you go through the following steps to perform the screening:<\/p>\n\n\n\n<p>Prepare an input file \u2014 supported formats:&nbsp;<code>.txt<\/code>,&nbsp;<code>.csv<\/code>,&nbsp;<code>.smi<\/code>, or Excel (<code>.xlsx<\/code>\/<code>.xls<\/code>).<\/p>\n\n\n\n<p>Each row in the input file should contain one&nbsp;<strong>SMILES code<\/strong>&nbsp;or one&nbsp;<strong>CAS number<\/strong>.<\/p>\n\n\n\n<p>Click&nbsp;<strong>Load File<\/strong>&nbsp;and select your file.<\/p>\n\n\n\n<p><strong>Input type<\/strong>&nbsp;is auto-detected (SMILES vs. CAS). You can override this with the radio buttons if needed.<\/p>\n\n\n\n<p>Click&nbsp;<strong>Start Screening<\/strong>.<\/p>\n\n\n\n<p><em>CAS mode:<\/em>&nbsp;the tool first resolves each CAS number to a SMILES via the PubChem API (~800 ms per entry). Progress is shown while it runs.<\/p>\n\n\n\n<p><em>SMILES mode:<\/em>&nbsp;classification runs immediately.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Input Format Tips<\/h4>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Input type<\/th><th class=\"has-text-align-left\" data-align=\"left\">Example<\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-left\" data-align=\"left\">SMILES<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>FC(F)(F)C(F)(F)F<\/code><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">CAS number<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>335-67-1<\/code>&nbsp;(PFOA)<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>For batch files, one entry per line is sufficient. Column headers are optional.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Interpreting Results<\/h4>\n\n\n\n<p>The classification is based on&nbsp;<strong>atom-level inspection<\/strong>&nbsp;of fully fluorinated carbon groups (CF\u2082, CF\u2083 with no H, Cl, Br, or I attached):<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>EU &amp; OECD PFAS<\/strong>&nbsp;\u2014 contains at least one such group, and it is not an isolated degradable moiety under EU rules.<\/li>\n\n\n\n<li><strong>OECD-only PFAS<\/strong>&nbsp;\u2014 contains such a group, but the EU exclusion applies (e.g. a single CF\u2083 connected via O or N).<\/li>\n\n\n\n<li><strong>Not PFAS<\/strong>&nbsp;\u2014 no qualifying fully fluorinated carbon found.<\/li>\n<\/ul>\n\n\n\n<p>Results appear in the&nbsp;<strong>list on the left<\/strong>, color-coded by category (see Picture 2).<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"565\" src=\"https:\/\/i0.wp.com\/kellerbits.net\/wordpress\/wp-content\/uploads\/2026\/05\/PFAS_ST_pic2a.jpg?resize=750%2C565&#038;ssl=1\" alt=\"\" class=\"wp-image-7557\" srcset=\"https:\/\/i0.wp.com\/kellerbits.net\/wordpress\/wp-content\/uploads\/2026\/05\/PFAS_ST_pic2a.jpg?resize=1024%2C771&amp;ssl=1 1024w, https:\/\/i0.wp.com\/kellerbits.net\/wordpress\/wp-content\/uploads\/2026\/05\/PFAS_ST_pic2a.jpg?resize=300%2C226&amp;ssl=1 300w, https:\/\/i0.wp.com\/kellerbits.net\/wordpress\/wp-content\/uploads\/2026\/05\/PFAS_ST_pic2a.jpg?resize=768%2C578&amp;ssl=1 768w, https:\/\/i0.wp.com\/kellerbits.net\/wordpress\/wp-content\/uploads\/2026\/05\/PFAS_ST_pic2a.jpg?resize=1536%2C1156&amp;ssl=1 1536w, https:\/\/i0.wp.com\/kellerbits.net\/wordpress\/wp-content\/uploads\/2026\/05\/PFAS_ST_pic2a.jpg?w=1641&amp;ssl=1 1641w\" sizes=\"auto, (max-width: 750px) 100vw, 750px\" \/><\/figure>\n\n\n\n<p><em>Picture 2: Screening result display view 1<\/em><\/p>\n\n\n\n<p>Click any entry to see the&nbsp;<strong>classification detail<\/strong>&nbsp;and render its structure on the right (see Picture 3).<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"661\" src=\"https:\/\/i0.wp.com\/kellerbits.net\/wordpress\/wp-content\/uploads\/2026\/05\/PFAS_ST_pic3a.jpg?resize=750%2C661&#038;ssl=1\" alt=\"\" class=\"wp-image-7559\" srcset=\"https:\/\/i0.wp.com\/kellerbits.net\/wordpress\/wp-content\/uploads\/2026\/05\/PFAS_ST_pic3a.jpg?resize=1024%2C902&amp;ssl=1 1024w, https:\/\/i0.wp.com\/kellerbits.net\/wordpress\/wp-content\/uploads\/2026\/05\/PFAS_ST_pic3a.jpg?resize=300%2C264&amp;ssl=1 300w, https:\/\/i0.wp.com\/kellerbits.net\/wordpress\/wp-content\/uploads\/2026\/05\/PFAS_ST_pic3a.jpg?resize=768%2C677&amp;ssl=1 768w, https:\/\/i0.wp.com\/kellerbits.net\/wordpress\/wp-content\/uploads\/2026\/05\/PFAS_ST_pic3a.jpg?resize=1536%2C1353&amp;ssl=1 1536w, https:\/\/i0.wp.com\/kellerbits.net\/wordpress\/wp-content\/uploads\/2026\/05\/PFAS_ST_pic3a.jpg?w=1648&amp;ssl=1 1648w\" sizes=\"auto, (max-width: 750px) 100vw, 750px\" \/><\/figure>\n\n\n\n<p><em>Picture 3: Screening result display view 2<\/em><\/p>\n\n\n\n<p>Click&nbsp;<strong>Export Report<\/strong>&nbsp;to save an Excel file with all results and embedded structure images. The resulting Excel report looks like shown in Picture 4.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"868\" src=\"https:\/\/i0.wp.com\/kellerbits.net\/wordpress\/wp-content\/uploads\/2026\/05\/PFAS_ST_pic3.jpg?resize=750%2C868&#038;ssl=1\" alt=\"\" class=\"wp-image-7560\" srcset=\"https:\/\/i0.wp.com\/kellerbits.net\/wordpress\/wp-content\/uploads\/2026\/05\/PFAS_ST_pic3.jpg?resize=885%2C1024&amp;ssl=1 885w, https:\/\/i0.wp.com\/kellerbits.net\/wordpress\/wp-content\/uploads\/2026\/05\/PFAS_ST_pic3.jpg?resize=259%2C300&amp;ssl=1 259w, https:\/\/i0.wp.com\/kellerbits.net\/wordpress\/wp-content\/uploads\/2026\/05\/PFAS_ST_pic3.jpg?resize=768%2C888&amp;ssl=1 768w, https:\/\/i0.wp.com\/kellerbits.net\/wordpress\/wp-content\/uploads\/2026\/05\/PFAS_ST_pic3.jpg?resize=1328%2C1536&amp;ssl=1 1328w, https:\/\/i0.wp.com\/kellerbits.net\/wordpress\/wp-content\/uploads\/2026\/05\/PFAS_ST_pic3.jpg?w=1418&amp;ssl=1 1418w\" sizes=\"auto, (max-width: 750px) 100vw, 750px\" \/><\/figure>\n\n\n\n<p><em>Picture 4: Excel report file from screening result<\/em><\/p>\n\n\n\n<p>You can now delete the screening result by clicking the button <strong>Clear<\/strong>, enabling another screening with a new CAS\/SMILES-containing list. The resulting Excel report is perfect for further analysis and review of the screening results separately from the tool. Please note also the mentioned input format tips above.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Literature &amp; Weblinks<\/h2>\n\n\n\n<p>[1] Gaines, L.G.T. (2023). Historical and current usage of per- and polyfluoroalkyl substances (PFAS): A literature review. American Journal of Industrial Medicine, 66(5), 353-378. https:\/\/doi.org\/10.1002\/ajim.23362<\/p>\n\n\n\n<p>[2] Gluge, J., Scheringer, M., Cousins, I.T., et al. (2020). An overview of the uses of per- and polyfluoroalkyl substances (PFAS). Environmental Science: Processes &amp; Impacts, 22(12), 2345-2373.<br>https:\/\/doi.org\/10.1039\/D0EM00291G<\/p>\n\n\n\n<p>[3] Garg, N.K. et al. (2024). C-F Bond Insertion: An Emerging Strategy for Constructing Fluorinated Molecules. Chemistry &#8212; A European Journal, 30(9). https:\/\/doi.org\/10.1002\/chem.202304229<\/p>\n\n\n\n<p>[4] Cousins, I.T., DeWitt, J.C., Gluge, J., et al. (2023). Forever chemicals: the persistent effects of perfluoroalkyl and polyfluoroalkyl substances on human health. eBioMedicine, 95, 104806.<br>https:\/\/doi.org\/10.1016\/j.ebiom.2023.104806<\/p>\n\n\n\n<p>[5] OECD (2021). Reconciling Terminology of the Universe of Per- and Polyfluoroalkyl Substances: Recommendations and Practical Guidance. ENV\/CBC\/MONO(2021)25.<br>https:\/\/one.oecd.org\/document\/ENV\/CBC\/MONO(2021)25\/En\/pdf<\/p>\n\n\n\n<p>[6] ECHA (2023). ANNEX XV Restriction Report &#8212; Per- and polyfluoroalkyl substances (PFASs). Submitted by Denmark, Germany, the Netherlands, Norway, and Sweden under REACH. European Chemicals Agency, Helsinki. https:\/\/echa.europa.eu\/documents\/10162\/f605d4b5-7c17-7414-8823-b49b9fd43aea<\/p>\n\n\n\n<p>[7] Landrum, G. RDKit: Open-Source Cheminformatics Software. https:\/\/www.rdkit.org (RRID: SCR_014274)<\/p>\n\n\n\n<p>[8] Kim, S., Chen, J., Cheng, T., et al. (2023). PubChem 2023 update. Nucleic Acids Research, 51(D1), D1373-D1380. https:\/\/doi.org\/10.1093\/nar\/gkac956<\/p>\n\n\n\n<p>[9] Source code available on Bitbucket at <a href=\"https:\/\/bitbucket.org\/nomapps\/pfas_screening_tool\">https:\/\/bitbucket.org\/nomapps\/pfas_screening_tool<\/a><\/p>\n\n\n\n<p>[Image] Cover picture generated with GPT Image 1 mini<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Abstract Per- and polyfluoroalkyl substances, commonly known as PFAS, are a group of thousands of synthetic chemicals manufactured since the 1940s [1, 2]. Their carbon-fluorine bonds, among the strongest single bonds in organic chemistry, with a bond dissociation energy of approximately 485 kJ\/mol [3], make them exceptionally resistant to heat, [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":7511,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[10,6],"tags":[],"class_list":["post-7510","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-python","category-software"],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/kellerbits.net\/wordpress\/wp-content\/uploads\/2026\/04\/PFAS_landscape_highres-scaled.jpg?fit=2560%2C1707&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/kellerbits.net\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/7510","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kellerbits.net\/wordpress\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kellerbits.net\/wordpress\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kellerbits.net\/wordpress\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/kellerbits.net\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=7510"}],"version-history":[{"count":22,"href":"https:\/\/kellerbits.net\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/7510\/revisions"}],"predecessor-version":[{"id":7578,"href":"https:\/\/kellerbits.net\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/7510\/revisions\/7578"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/kellerbits.net\/wordpress\/index.php?rest_route=\/wp\/v2\/media\/7511"}],"wp:attachment":[{"href":"https:\/\/kellerbits.net\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=7510"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kellerbits.net\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=7510"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kellerbits.net\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=7510"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}