Skip to content
Snippets Groups Projects
DxReader.py 3.97 KiB
Newer Older
  • Learn to ignore specific revisions
  • DIANE's avatar
    DIANE committed
    from Packages import * 
    
    DIANE's avatar
    DIANE committed
    import jcamp as jc
    
    DIANE's avatar
    DIANE committed
    
    
    DIANE's avatar
    DIANE committed
    class DxRead:
    
    DIANE's avatar
    DIANE committed
    
        '''This module is designed to help retrieve spectral data as well as metadata of smaples  from jcamp file'''
        def __init__(self, path):
    
    DIANE's avatar
    DIANE committed
            #self.__path = path.replace('\\','/')
            self.__path = path
    
    DIANE's avatar
    DIANE committed
            self.__dxfile = jc.jcamp_readfile(self.__path)
            
            # Access samples data
            self.__nb = self.__dxfile['blocks'] # Get the total number of blocks = The total number of scanned samples
            self.__list_of_blocks = self.__dxfile['children']  # Store all blocks within a a list
            self.__wl = self.__list_of_blocks[0]["x"] # Wavelengths/frequencies/range 
            
    
    
            # Start retreiving the data
            specs = np.zeros((self.__nb, len(self.__list_of_blocks[0]["y"])), dtype=float) # preallocate a np matrix for sotoring spectra
            self.idx = np.arange(self.__nb) # This list is designed to store samples name
            self.__met = {}
    
    
            for i in range(self.__nb): # Loop over the blocks
                specs[i] = self.__list_of_blocks[i]['y']
                
    
    DIANE's avatar
    DIANE committed
                block = self.__list_of_blocks[i]
                block_met = {   'name': block['title'],
                                'origin': block['origin'],
                                'date': block['date'],
    
                #                'time': block['time'],
                #                'spectrometer/data system': block['spectrometer/data system'],
                #                'instrumental parameters': block['instrumental parameters'],
                #                'xunits': block['xunits'],
                #                'yunits': block['yunits'],
                #                'xfactor': block['xfactor'],
                #                'yfactor': block['yfactor'],
                #                'firstx': block['firstx'],
                #                'lastx': block['lastx'],
                #                'firsty':block['firsty'],
                #                'miny': block['miny'],
                #                'maxy': block['maxy'],
                #                'npoints': block['npoints'],
    
    DIANE's avatar
    DIANE committed
                                'concentrations':block['concentrations'],
    
                #                'deltax':block['deltax']
    
    DIANE's avatar
    DIANE committed
                                }
                self.__met[f'{i}'] = block_met
            self.metadata_ = pd.DataFrame(self.__met).T
                
    
            self.spectra = pd.DataFrame(np.fliplr(specs), columns= self.__wl[::-1]) # Storing spectra in a pd.dataframe
    
    
    
            #### Concentrarions
            self.pattern = r"\(([^,]+),(\d+(\.\d+)?),([^)]+)"
            aa = self.__list_of_blocks[0]['concentrations']
            a = '\n'.join(line for line in aa.split('\n') if "NCU" not in line and "<<undef>>" not in line)
            n_elements = a.count('(')
    
            ## Get the name of analyzed chamical elements
            elements_name = []
            for match in re.findall(self.pattern, a):
                    elements_name.append(match[0])
    
            ## Retrieve concentrationds
            df = self.metadata_['concentrations']
            cc = {}
            for i in range(self.metadata_.shape[0]):
                cc[df.index[i]] = self.conc(df[str(i)])
    
            ### dataframe conntaining chemical data
    
    DIANE's avatar
    DIANE committed
            self.chem_data = pd.DataFrame(cc, index=elements_name).T.astype(float)
    
    DIANE's avatar
    DIANE committed
    
        ### Method for retrieving the concentration of a single sample
        def conc(self,sample):
            prep = '\n'.join(line for line in sample.split('\n') if "NCU" not in line and "<<undef>>" not in line)
            c = []
            for match in re.findall(self.pattern, prep):
                    c.append(match[1])
            concentration = np.array(c)
            return concentration
    
        @property
        def specs_df_(self):
            return self.spectra
        @property
        def md_df_(self):
    
            return self.metadata_.drop("concentrations", axis = 1)
    
    DIANE's avatar
    DIANE committed
        
        @property
        def chem_data_(self):
    
             return self.chem_data
        
    @st.cache_data
    def read_dx(file):
         M = DxRead(file)
         return M.chem_data, M.specs_df_, M.md_df_