Advertisement
shihab2196

REACTER_Module-lfp_reactionVStime_A0001_variable_Rmax

Dec 8th, 2024
55
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 11.91 KB | None | 0 0
  1. '''Created by Fakhrul Hasan Bhuiyan'''
  2.  
  3. ##### Edit history #######
  4.  
  5. # Fakhrul H Bhuiyan: 10.13.2020 | Finalized the first version of the module
  6. # Fakhrul H Bhuiyan: 10.28.2020 | Fixed issues: Same thermodynamic keyword as header
  7. #                               | Incomplete line in the data block
  8. #                               | Added a new flag: 'Per MPI rank memory allocation'
  9. # Shihab Ahmed: 04:06:2024      | Define thermo_panda function
  10.  
  11. from warnings import showwarning, warn
  12. import numpy as np
  13. from scipy.optimize import curve_fit
  14. import sys
  15. import pandas as pd
  16.  
  17. def thermo_dict(filename, serial):
  18.     with open(filename, 'r') as f:
  19.         start = 0
  20.         thermo_data = {}
  21.  
  22.         for step, line in enumerate(f):
  23.             #print (line)
  24.             if line.startswith('Memory usage per processor') or line.startswith('Per MPI rank memory allocation'):   # looks for this line in the file
  25.                 #print('start')
  26.                 start += 1      # seed for start taking in data
  27.                 data_row = 0    # this is equal to the line number of the data
  28.                 thermo_headers = []     # thermo information in log files
  29.                 continue
  30.             if start == serial:     # if the code reaches the desired portion of the log file
  31.                 data_row += 1
  32.                 data = line.split()
  33.                 if data_row == 1:   # in the first line you have the headers
  34.                     for i in (data):
  35.                         if i not in thermo_headers:
  36.                             thermo_headers.append(i)    # creating a list of str of headers
  37.                             thermo_data[i] = []         # Creating dictionary keys named after each thermodynamic property
  38.                         else:
  39.                             # There are identical thermodynamic keywords as header
  40.                             name = i + '_' + str(data.index(i) + 1)
  41.                             thermo_headers.append(name)
  42.                             thermo_data[name] = []
  43.                             showwarning('Log file has same Thermodynamic keyword ' + str(i),
  44.                                         UserWarning, 'log_parser_FHB.py', 31)
  45.  
  46.                     #print ('len', len(thermo_data), thermo_data)
  47.  
  48.                 elif data_row > 1:      # this is where the data information starts in the log file
  49.                     #print (start)
  50.                     for i in range(0, len(data)):
  51.                         try:
  52.                             data[i] = float(data[i])  # making the str to float
  53.  
  54.                             if len(data) != len(thermo_headers):    # checking if the data line is complete
  55.                                 showwarning('Line number: ' + str(step+1) + ' in the log file is incomplete.',
  56.                                             UserWarning, 'log_parser.py', 46)
  57.                                 #print (data)
  58.                                 break
  59.                             else:
  60.                                 thermo_data[thermo_headers[i]].append(
  61.                                     data[i])  # putting in the data info in respective header's dict
  62.                         except:
  63.                             start += 1
  64.                             #print ('breaking')
  65.                             break  # if data lines end, you get str again, this terminates taking any more data
  66.  
  67.  
  68.  
  69.  
  70.     #print (thermo_data['Step'])
  71.     ##print (thermo_data['KinEng'])
  72.     #for x in thermo_data: print (x)
  73.     f.close()
  74.    
  75.     from colorama import Fore, Style
  76.     print(Fore.CYAN + '#### From log_parser: Serial = {}, Total Steps = {} ####'.format(serial,len(thermo_data['Step'])),end='')
  77.     print(Style.RESET_ALL)
  78.  
  79.  
  80.     return thermo_data      # Returns the whole dictionary
  81.  
  82.  
  83. ##############
  84. #   Created by Shihab from here
  85. #   Date: 4/18/2023
  86. ##############
  87.  
  88.  
  89.  
  90. def thermo_dict_v2(filename, serial):              
  91.     ## Local Function That can be called ##
  92.     def thermo_serial(filename,serial):
  93.         with open(filename, 'r') as f:
  94.             start = 0
  95.             thermo_data = {}
  96.    
  97.             for step, line in enumerate(f):
  98.                 #print (line)
  99.                 if line.startswith('Memory usage per processor') or line.startswith('Per MPI rank memory allocation'):   # looks for this line in the file
  100.                     #print('start')
  101.                     start += 1      # seed for start taking in data
  102.                     data_row = 0    # this is equal to the line number of the data
  103.                     thermo_headers = []     # thermo information in log files
  104.                     continue
  105.                 if start == serial:     # if the code reaches the desired portion of the log file
  106.                     data_row += 1
  107.                     data = line.split()
  108.                     if data_row == 1:   # in the first line you have the headers
  109.                         for i in (data):
  110.                             if i not in thermo_headers:
  111.                                 thermo_headers.append(i)    # creating a list of str of headers
  112.                                 thermo_data[i] = []         # Creating dictionary keys named after each thermodynamic property
  113.                             else:
  114.                                 # There are identical thermodynamic keywords as header
  115.                                 name = i + '_' + str(data.index(i) + 1)
  116.                                 thermo_headers.append(name)
  117.                                 thermo_data[name] = []
  118.                                 showwarning('Log file has same Thermodynamic keyword ' + str(i),
  119.                                             UserWarning, 'log_parser_FHB.py', 31)
  120.    
  121.                         #print ('len', len(thermo_data), thermo_data)
  122.    
  123.                     elif data_row > 1:      # this is where the data information starts in the log file
  124.                         #print (start)
  125.                         for i in range(0, len(data)):
  126.                             try:
  127.                                 data[i] = float(data[i])  # making the str to float
  128.    
  129.                                 if len(data) != len(thermo_headers):    # checking if the data line is complete
  130.                                     showwarning('Line number: ' + str(step+1) + ' in the log file is incomplete.',
  131.                                                 UserWarning, 'log_parser.py', 46)
  132.                                     #print (data)
  133.                                     break
  134.                                 else:
  135.                                     thermo_data[thermo_headers[i]].append(
  136.                                         data[i])  # putting in the data info in respective header's dict
  137.                             except:
  138.                                 start += 1
  139.                                 #print ('breaking')
  140.                                 break  # if data lines end, you get str again, this terminates taking any more data
  141.         return thermo_data
  142.  
  143.    
  144.     if type(serial) in [list,tuple]:
  145.         result = {}
  146.         for s in serial:
  147.             thermo = thermo_serial(filename,s)
  148.            
  149.             for key,value in thermo.items():
  150.                 if key in result.keys():
  151.                     result[key] +=thermo[key]
  152.                 else:
  153.                     result[key] = thermo[key]
  154.          
  155.     else:
  156.         result = thermo_serial(filename, serial)
  157.            
  158.            
  159.     from colorama import Fore, Style
  160.     print(Fore.CYAN + '#### From log_parser: Serial = {}, Total Steps = {} ####'.format(serial,len(result['Step'])),end='')
  161.     print(Style.RESET_ALL)
  162.  
  163.  
  164.     return result      # Returns the whole dictionary
  165.  
  166.  
  167. def thermo_panda(logfile, serial,
  168.                  start_string = 'Per MPI',
  169.                  end_string   = 'Loop time',
  170.                  zero_ref : str = None):
  171.     '''
  172.    zero_ref: str
  173.    Specifies which variables to apply zero-referencing to.
  174.    Options include:
  175.        - "energy": Apply zero-referencing to all energy (tot, pe, ke) columns.
  176.        - "time": Apply zero-referencing to time values.
  177.        - "energy+time" or "time+energy": Apply zero-referencing to both energy and time.
  178.    The values can be combined using an underscore (+) in any order.
  179.    '''
  180.    
  181.     timestep=None # starting None value
  182.    
  183.     start_lines  = []
  184.     end_lines    = []
  185.     with open(logfile, 'r') as file:
  186.         for i, line in enumerate(file):
  187.             if start_string in line:
  188.                 start_lines.append(i)
  189.             if end_string in line:
  190.                 end_lines.append(i)
  191.            
  192.             # getting timestep
  193.             if line.strip().startswith('timestep'):
  194.                 try:
  195.                     timestep=float(line.split('#')[0].split()[1])
  196.                 except:
  197.                     pass
  198.                 else:
  199.                     print(f'timestep found from the log file: {timestep}')
  200.    
  201.     if timestep is None:
  202.         raise ValueError("No 'timestep' value is found")
  203.                
  204.     if len(start_lines)!=len(end_lines):
  205.         print('Warning: Log file is incomplete')
  206.         end_lines.append(i)
  207.        
  208.     feed = list(zip(start_lines,end_lines))  
  209.    
  210.     if serial=='all':
  211.         thermo_list = []  # Create an empty list to store dataframes
  212.         for f in feed:
  213.             start, end = f
  214.             # Read each serial and append it to the list of thermos
  215.             thermo_part = pd.read_csv(logfile, sep=r'\s+', skiprows=start+1,
  216.                                       nrows=end-start-2)
  217.             thermo_list.append(thermo_part)  # Append the read data to the list
  218.        
  219.         # Combine all the individual thermos into one dataframe
  220.         thermo = pd.concat(thermo_list, ignore_index=True)
  221.        
  222.     elif isinstance(serial,int):
  223.         if serial>len(feed):
  224.             raise ValueError(f'Only {len(feed)} serial exists but found {serial}')
  225.            
  226.         start, end = feed[serial-1]
  227.         thermo = pd.read_csv(logfile,sep=r'\s+',skiprows=start+1,
  228.                            nrows=end-start-2)
  229.        
  230.     elif isinstance(serial,list):
  231.         if any(s > len(feed) for s in serial):
  232.             raise ValueError('Found a serial number greater than '
  233.                              f'the total number of serials ({len(feed)}).')
  234.        
  235.         # check what if serials are not consecutive
  236.         # under construction
  237.        
  238.         thermo_list = []  # Create an empty list to store dataframes
  239.  
  240.         for s in serial:
  241.             start, end = feed[s-1]
  242.             # Read each serial and append it to the list of thermos
  243.             thermo_part = pd.read_csv(logfile, sep=r'\s+', skiprows=start+1,
  244.                                       nrows=end-start-2)
  245.             thermo_list.append(thermo_part)  # Append the read data to the list
  246.        
  247.         # Combine all the individual thermos into one dataframe
  248.         thermo = pd.concat(thermo_list, ignore_index=True)
  249.            
  250.         print('Code is under construction..')
  251.     else:
  252.         raise TypeError("Serial must be a single int or an array of int or 'all'")
  253.    
  254.     # Time column
  255.     ps = thermo['Step']*timestep/1000
  256.     thermo['Time'] = ps
  257.        
  258.     if zero_ref:
  259.         zrefs = zero_ref.split('+')
  260.         for z in zrefs:
  261.             if z.lower()=='energy':
  262.                 energy_columns = ['PotEng', 'TotEng', 'KinEng']
  263.                 for col in energy_columns:
  264.                     if col in thermo.columns:
  265.                         thermo[col] = thermo[col] - thermo[col].min()
  266.                        
  267.             elif z.lower()=='time':
  268.                 if 'Time' in thermo.columns:
  269.                     thermo['Time'] = thermo['Time'] - thermo['Time'].min()
  270.            
  271.             else:
  272.  
  273.                 warn(f"The 'zero_ref' parameter '{z}' is not recognized. "
  274.                     "Please use 'energy', 'time', or a combination of them.",
  275.                     UserWarning
  276.                 )
  277.                 print()
  278.  
  279.     return thermo
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement