Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create a matrix of 1 and zeros to mask out Rayleigh-Tyndall lines in R

Tags:

r

matrix

I am doing fluorescence spectroscopy and process the files afterwards with R. I would like to create a matrix of 1 and 0 such that I can mask out the Rayleigh-Tyndall lines from the excitation-emission-matrices (EEM).

The EEMs have 44 columns (excitations) and 602 rows (emissions). The excitation wavelengths range from 240 to 455 nm in 5 nm steps. The emission wavelengths range from 300 to 600.5 in 0.5 nm steps. The resulting matrix to mask out should look something like this (This is just a small cut out of the mask out matrix. The actual matrix is 44*602 in size):

    240 245 250 ... 300 305 310 ... 455
300   1   1   1 ...   0   1   1 ...   1
300.5 1   1   1 ...   1   1   1 ...   1
...
305   1   1   1 ...   1   0   1 ...   1
...
310   1   1   1 ...   1   1   0 ...   1
...
480   0   1   1 ... 
...  
600   1   1   1 ...   0   1   1 ...
600.5 ...

When the mask out matrix (the one desired) is created I want to multiply it with the actual EEM values. Something like this should then do the trick:

corrected_EEM_Intensity <- Mask.Matrix * Sample_EEM

The EEMs look like this (44 columns * 602 rows in size):

        240  245 ... 455
300   202.7  ...
300.5 190.5  ... 
...   ....   ...
600    82.4  ...
600.5  45.9  ...

So I would like to divide the excitations through the emissions and vice verse. In case the emission is a factor of the excitaton and vice versa there should be a 0 in the matrix. In other cases there should be a 1.

To make things more complicated I would like to do it not just for the corresponding factors but within a range of 10 nm. This means that for example excitation 430 divided by emission 440, and excitation divided by 450 should also give a 0.

The real mask out matrix should then look something like this (meant as short example):

    240  ... 400 ... 455
300   1
300.5 1  ...   1 ...   1
...   1    1   1   1   1
...
390   1    1   0   1   1
...   1    1   0   1   1
400   1    1   0   1   1
...
600
600.5 1    1   1   1   1

How can I do this? After a lot of research and some own trials, I could not find an answer to this.

like image 919
Strohmi Avatar asked Jan 25 '26 13:01

Strohmi


1 Answers

If you mean to test for pairs where a is a factor of b, or vice versa, you can use the following (EDIT: this now considers a modulo of <= 10 as being zero, i.e. if a is within 10 of a factor of b, the corresponding matrix cell is set to zero):

cols <- seq(240, 455, 5)
rows <- seq(300, 600.5, 0.5)
# Create a two-column matrix containing all possible excitation-emission pairs.  
d <- expand.grid(rows, cols, stringsAsFactors=FALSE)

# For each pair, test whether the smaller is a factor of the larger
# Set the number on the right hand side of the comparison (<=) to the 
#  maximum distance (from a true factor) within which numbers will be
#  considered factors.
test <- apply(d, 1, function(x) max(x) %% min(x) <= 10)

# Create a matrix and populate with the (inverse) outcome of the test
res <- matrix(as.numeric(!test), ncol=44, nrow=602,
              dimnames=list(rows, cols))

# Partial output
res[c('300', '300.5', '305', '310', '430', '480'), 
    c('240', '245', '250', '300', '305', '310', '440', '455')]
#      240 245 250 300 305 310 440 455
#300     1   1   1   0   0   0   1   1
#300.5   1   1   1   0   0   0   1   1
#305     1   1   1   0   0   0   1   1
#310     1   1   1   0   0   0   1   1
#430     1   1   1   1   1   1   0   1
#480     0   1   1   1   1   1   1   1
like image 97
jbaums Avatar answered Jan 28 '26 02:01

jbaums