What steps should I follow to transform SRM into L*a*b* values using the E-308 algorithm?

I'm grappling with the application of ASTM E-308 to SRM measurements in beer. The project I'm working on necessitates a reliable conversion from SRM to RGB (or sRGB) through the Lab* route. It's clear that each site I visit for beer recipe creation has its own unique SRM to RGB conversion method, given the complexity of the task. To address this issue, I am considering developing an open-source JavaScript library to tackle this challenge.

My approach involves using an algorithm outlined here:

This algorithm is believed to be a simplified version of the E-308 algorithm. However, I'm facing difficulty when referencing the spreadsheet provided in the linked post (). Selecting a XYZ vector based on the observer angle specified in the spreadsheet (such as a 10-degree observer angle) raises questions. For instance, if I opt for a 10-degree observer angle, should the corresponding XYZ vector be (82.82, 3.48, 61.86)? Is this calculation correct?

Additoinally, choosing an illuminant spectrum adds another layer of complexity. If I choose illuminant C (presumed to have a color temperature of 6774K), how do I determine and incorporate the appropriate components into the spectrum? How are these components calculated in the first place?

While I have some understanding of color theory, what I truly aim for is a streamlined process where I can input certain criteria like observer angle, illuminant color temperature, as well as the SRM value, and obtain the corresponding Lab* value.

Answer №1

This particular issue requires an answer that may not align with the usual format of Stack Overflow.

ASTM E308 is a detailed and lengthy standard spanning around 50 pages, primarily focusing on converting spectral distribution to CIE XYZ tristimulus values. It also delves into conversions to CIE Lab and CIE Luv.

The spreadsheet mentioned in your query does not fully adhere to ASTM E308 and takes liberties by utilizing the integration method for 5 nm measurement intervals without including a table of tristimulus weighting factors necessary in case of bandpass corrected spectral data. While suitable for practical purposes, it's crucial to note that precision demands strict adherence to ASTM E308.

The complexity of the spreadsheet arises from its utilization of the Augmented SRM computation involving eigen-vectors for numerous beers.

Should you be inclined towards applying the ASBC method, this should be your course of action:

  • Determine the beer transmission spectral distribution based on the given SRM and path length using the provided equation

https://i.sstatic.net/uqFVd.png

  • Convert the spectral distribution to CIE XYZ tristimulus values using the integration method for the CIE 1964 10 Degree Standard Observer and Illuminant C
  • Further convert the CIE XYZ tristimulus values to CIE Lab
  • Additionally, convert them to sRGB
  • And finally, enjoy the beer :)

If Python is within your reading spectrum, a Colab notebook has been crafted which employs Colour to compute beer color across various SRM values and path lengths:

(Python code snippet here)

https://i.sstatic.net/KGYQU.png

A suggestion is made regarding the ease of implementing Colour within a container through Flask in the backend, which can then be accessed via Javascript. Moreover, an advanced 3D visualizer is available if exploring that avenue appeals to you.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Design a recurring report using an endless JavaScript cycle

I am in the process of creating a brand new scheduled report and have encountered an issue. How can I incorporate a script that includes a loop to run a specific function every 10 seconds? Here's what I have so far: var count = 1; while(count > 0 ...

Is it possible to submit a HTML5 form and have it displayed again on the same page?

Is it possible to simply reload the sidebar of a page containing an HTML5 form upon submission, or is it necessary to load a duplicate page with only the sidebar changed? I am unsure of how to tackle this situation; firstly, if it is achievable in this m ...

The functionality of Javascript Regular Expressions is not performing as expected

I am currently facing an issue with email validation in JavaScript as it doesn't seem to be working properly. PROBLEM: Even when entering a VALID email address, the alert still shows that my address is faulty... What could I possibly be missing he ...

Have you ever wondered why the expression `Number(new Boolean(false))` always returns `0

In the case of Boolean(new Boolean(...)) === true, it is because new Boolean(...) is treated as an object. However, why does Number(new Boolean(false)) === 0 (+new Boolean(false) === 0) and Number(new Boolean(true)) === 1? Instead of resulting in NaN. Wh ...

Traversing an array of objects in TypeScript and appending to a separate array if not already present

I have been given an array containing objects in the following format: export interface Part { workOrder?: string; task?: string; partNumber?: string; qty?: number; image?: string; name?: string; } My goal is to loop through each object in th ...

Adjust CSS classes as user scrolls using skrollr

I am currently facing an issue with the prinzhorn/skrollr plugin when trying to use removeClass/addClass on scroll function. I have attempted to find a solution but unfortunately, nothing has worked for me. <li class="tab col s3"><a data-800="@cl ...

What steps can I take to refactor a portion of the component using React hooks?

I am trying to rewrite the life cycle methods in hooks but I am facing some issues. It seems like the component is not behaving as expected. How can I correct this? Can you provide guidance on how to properly rewrite it? useEffect(() => { updateUs ...

What is the best approach to setting up dynamic Vue routing?

I am working on implementing dynamic routing for the website that relies on changes in agreements. Here is the path tree I have set up: const routes = [ { path: "/", redirect: "/home", component: DefaultLayou ...

Tips on sending a form to the server with ajax technology

I'm struggling with sending a button id to my server through ajax in order to submit a form without having to constantly reload the page every time I click on a button. Unfortunately, it's not working as expected and I can't figure out why. ...

Tips for accessing <Field> values in redux-form version 7.0.0

class CustomForm extends React.Component { constructor(props) { super(props); this.handleClick = this.handleClick.bind(this); } handleClick() { const { Add, noteList } = this.props; Add('this is title value' , 'this is ...

Manipulating arrays of objects with handlebars.js

I need help with my node.js app that is returning JSON data for computers. { computers: { john: { cpu: "intel", ram: "8MB", hd: "1TB" }, jane: { cpu: "intel", ram: "12MB", hd: "500GB" }, mary: { ...

The React-Leaflet curly braces positioned on the top left corner of the map

Is there a way to remove the curly braces and symbols near the zoom pane when the map is too far? https://i.stack.imgur.com/eGQCd.png p.s. Here is some provided code for reference: p.s. 2 - I have noticed that adding a condition like {condition1 &a ...

Issue with React and Material UI: The Textfield's "onChange" event is not being triggered

I have been attempting to trigger an onchange function when my Textfield is populated, but for some reason the function never seems to be activated. Despite seeing changes triggered by the React devtool plugin in Chrome, I am at a loss. Any suggestions? i ...

Arranging an array in reverse order (starting with underscore) can alter the attributes of the objects within

REVISION: To provide more clarity on the issue, I have recorded a bug using quicktime. Here is the link for your reference: For additional code details, please visit: ORIGINAL INQUIRY: A strange issue has come up while working with Meteor and its depen ...

Create a personalized edit button for ContentTools with a unique design

I'm struggling to figure out how to customize the appearance and location of the edit button in ContentTools, a wysiwyg editor. After some research, I learned that I can use editor.start(); and editor.stop(); to trigger page editing. However, I want ...

Tips for implementing validations on a table that changes dynamically

I encountered an issue in my code while working on a dynamic form for age with unobtrusive client-side validation. The problem is that the validation is row-wise, but it behaves incorrectly by removing other rows' validations when I change one. Below ...

What is the best way to retrieve information from a database using JSON with PHP, JQUERY, and

Trying to retrieve data from a MySQL database and pass it to a JavaScript file has been quite a challenge. Despite searching extensively online, the examples I found didn't work in my specific scenario. .html file <!DOCTYPE html PUBLIC '-//W ...

Guide to defining API elements in Bootstrap 5 modal

I have been struggling with this issue for quite some time. I am working on a movie app and trying to implement a modal feature. Currently, I am able to display each movie individually along with their poster, title, and score. The goal is to have the mod ...

Avoid using sleep statements in Webdriverjs to prevent stale element reference issues

I've come across a block of code that utilizes action sequences to execute the following steps: click on a link that directs to a specific page wait for an input field to become visible on the page click on the input field clear any existing text in ...

Utilizing DOMPDF in conjunction with jQuery to generate PDF files

Apologies for any language errors in my writing. I am attempting to generate a PDF using a portion of HTML, utilizing jQuery, Ajax, and DomPDF. On the server side, I am using the following code: require_once './dompdf/autoload.inc.php'; if(!em ...