wincowgerDEV / OpenSpecy-package

Analyze, Process, Identify, and Share, Raman and (FT)IR Spectra
http://wincowger.com/OpenSpecy-package/
Creative Commons Attribution 4.0 International
23 stars 11 forks source link

[Feature]: Automated Matching #119

Closed wincowgerDEV closed 12 months ago

wincowgerDEV commented 1 year ago

Guidelines

Description

Garth C created this routine for automated matching with the standard package. Hopefully there are somethings we can reuse from that.

Problem

No

Proposed Solution

library(dplyr)
library(OpenSpecy)
library(stringr)
library(ggplot2)
library(foreach)

analyze_particles <-
  function(spectra) {
    spec_lib <-
      load_lib(which = "raman")  # load the spectral library

    output <- list()  # initialize lists and vectors for the loops
    wavenumber <- numeric()
    intensity <- numeric()
    identity <- numeric()
    rsq <- numeric()
    match <- data.frame()

    for (i in 1:(nrow(spectra) - 1)) {
      for (j in 1:(ncol(spectra) - 1)) {
        wavenumber[j] = spectra[1, j + 1]
        intensity[j] = spectra[i + 1, j + 1]
      }
      data <- data.frame(wavenumber,
                         intensity)
      output[[i]] <- data
    }

    ## Now loop over all particles and output summary data

    parallel::detectCores()

    n.cores <- parallel::detectCores() - 1  # set core number

    #create the cluster
    my.cluster <- parallel::makeCluster(n.cores,
                                        type = "PSOCK")

    #register it to be used by %dopar%
    doParallel::registerDoParallel(cl = my.cluster)

    match <- foreach(i = 1:length(output)) %dopar% {
      match <- OpenSpecy::match_spec(
        output[[i]],
        library = spec_lib,
        which = "raman",
        type = "full",
        top_n = 1
      )
    }

    parallel::stopCluster(my.cluster)

    identity <- unlist(lapply(match, function(x)
      x[1, 2]))
    rsq <- unlist(lapply(match, function(x)
      x[1, 3]))

    spec_summary <-
      data.frame(particle_number = seq(1, length(identity)),
                 identity, rsq)

    ## Add indicators for whether particles are PE, PS, PET, PC, or something else
    ## PE
    spec_summary$PE <- ifelse(str_detect(spec_summary$identity, 
                                         "LDPE|olyeth"),
                              1,
                              0)
    ## PS
    spec_summary$PS <- ifelse(str_detect(spec_summary$identity, 
                                         "PS|tyrene"),
                              1,
                              0)
    ## PET
    spec_summary$PET <- ifelse(str_detect(spec_summary$identity, 
                                          "PET|terephtalate"),
                               1,
                               0)
    ## Remove PE that is actually PET
    spec_summary$PE[spec_summary$PET == 1] <- 0
    ## PC 
    spec_summary$PC <- ifelse(str_detect(spec_summary$identity, 
                                         "olycarb"),
                              1,
                              0)

    spec_summary$other <- with(spec_summary, ifelse(PE == 1 |
                                                      PS == 1|
                                                      PET == 1|
                                                      PC == 1,
                                                    0,
                                                    1))
    return(spec_summary)
  }

Alternatives Considered

With the new open specy file format we may not be able to reproduce this exactly.

wincowgerDEV commented 12 months ago

Implemented in package now! Thanks Garth for the inspiration!