Skip to content

Commit

Permalink
initial upload
Browse files Browse the repository at this point in the history
  • Loading branch information
luisnovaish committed Jun 25, 2020
0 parents commit fb0c3a1
Show file tree
Hide file tree
Showing 6 changed files with 238 additions and 0 deletions.
190 changes: 190 additions & 0 deletions ImPSCAD/PSCADVar.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
###########################################################################
# Libraries and packages
###########################################################################
import os
import re
import math
import pandas as pd
import numpy as np


###########################################################################
# Definition of class
###########################################################################

class PSCADVar(object):
""" Documentation:
This class reads the .out files and returns all of the variables in it contained, as well as the header of the variables, time step and number of variables imported.
INF_path: str, mandatory.
It's the path of the .inf file
writecsv: bool, optional.
Creates a new .CSV file with the .OUT variables
delout: bool, optional.
Deletes the .OUT files once they were already read
"""

def __init__(self, INF_path, **kwargs):

# Default definitions of arguments:
# It WILL create a CSV file
# It WILL NOT delete the .OUT files

try:
kwargs['writecsv']
except KeyError:
kwargs['writecsv'] = True

try:
kwargs['delout']
except KeyError:
kwargs['delout'] = False


with open(INF_path) as myfile: # Open all the lines in the inf path
lines = myfile.readlines()


############################################################################
# Take the header of the values
############################################################################

n_col = 11 # Number of columns that the txt has
n_var = len(lines) # Number of PSCAD Variables
n_files = int(math.ceil(n_var / 10.0)) # Number of .out Files exported (the floating is important)
n_var_tot = n_var + n_files # Number of variables INCLUDING additional time column FOR EACH .OUT
n_var_last = n_var_tot -(n_files-1)*n_col # Number of variables in the last file
n_var_exp = n_var + 1 # Number of variables that will be exported

self.number_var = n_var_exp

# This "for" gets the number of columns of every file which will be all 11,
# but the last, which value can vary

last_col = [0]*n_files

for ii in range(0,n_files):

if ii != n_files-1:
b = n_col
else:
b = n_var_last

last_col[ii] = b

# last_col = [11, 11, 11, 1]

pattern = "Desc=\"(.*?)\"" # Patter that holds the variable name
header1 = [0] * (n_var_exp) # create a LIST of zeros that will be filled with the variables names later
self.header = [0] * (n_var_exp)

b = 0 # to "freeze" the time when storing the "TIME"
c = 1 # used in the index: from 1 to 11

# "For" Logic: each file can take 11 variables, and the first one is TIME
# so this for writes time if it is the time column, or takes the header from
# the array "header"

for a in range(0, n_var_exp):

if a == 0 : # if it is the first value of all files, storage the time name
header1[a] = 'self.time' # 1 header has the 'self.' in order to create variables to send
self.header[a] = 'time' # to the object outside
b = b - 1
if a != 0:
c = 1
else:
header1[a] = 'self.' + re.search(pattern, lines[b]).group(1) # gets the name of the variable from the line
header1[a] = header1[a].replace(" ", "_") # If the header has spaces, it will be replaced
self.header[a] = re.search(pattern, lines[b]).group(1)
self.header[a] = self.header[a].replace(" ", "_")
# print a, self.header[a] # USE "a+1" for range 1 to numb_variables, "c" for range 1 to 11


b = b + 1
c = c + 1

############################################################################
# Take all the paths of the .out files
############################################################################

# Create the path of each file so you can open it and read the values
# The "for" takes off the ending .inf and replace it with "_0NUMBER".out

OUT_name = [0] * n_files
OUT_path = [0] * n_files

for ii in range(0, n_files):
if ii < 9:
OUT_name[ii] = "_0" + str(ii + 1) + ".out" # Create ending "_0ii".out
OUT_path[ii] = INF_path.replace(".inf", OUT_name[ii]) # replace in INF_path the.inf for the new end
else:

OUT_name[ii] = "_" + str(ii + 1) + ".out" # Create ending "_0ii".out
OUT_path[ii] = INF_path.replace(".inf", OUT_name[ii]) # replace in INF_path the.inf for the new end


# print CSV_path[ii]

# Creates the path of the .CSV that's gonna be writen
CSV_path = INF_path.replace(".inf", ".csv") # Replaces the ending .inf with .csv

############################################################################
# SAVE header and Variables in one .CSV file
############################################################################

df_csv = pd.DataFrame() # Create an empty pandas dataframe that will storage all the data from the .outs

c = 0 # freezes the header if you skip time
jj = 0

for ii in range(0,n_files): # For each file, read it and storage its columns in the .CSV file

df = pd.read_csv(OUT_path[ii], delim_whitespace=True, header=None) # Read the .OUT file and storage it in a pandas data frame

if (jj == 0) or (jj % 11 == 0): # if it is a multiple of 11, means that it's another file
jj = 0 # so you reset the counter

while jj < last_col[ii]: # While you are inside the file, save values

if (jj == 0) and (ii == 0): # It is the first column of the first file: storage time
df_csv[self.header[c]] = df[jj]
elif (jj == 0) and (ii != 0): # It is the first column of some other file: don't storage time
jj = jj + 1
df_csv[self.header[c]] = df[jj]
# print 'just skipped time'
else:
df_csv[self.header[c]] = df[jj] # It is other column: storage column

exec('%s = np.array(%s)' % (header1[c],'df[jj]'))
# print df_csv.head()

# print c
c = c + 1
jj = jj + 1


if kwargs['delout'] == True: # If user wants to delete the .OUT files:
os.remove(OUT_path[ii])

############################################################################
# Gets the step of simulation - PSCAD
############################################################################

self.step = self.time[1] - self.time[0]


############################################################################
# Storage data in a.CSV file with all the variables
############################################################################

if (kwargs['writecsv'] == True):

df_csv.to_csv(CSV_path,index=False) # Storage all the dataframe into one csv file with header




1 change: 1 addition & 0 deletions ImPSCAD/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from ImPSCAD.PSCADVar import PSCADVar
Empty file added LICENSE.txt
Empty file.
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# GetVar

**Motivation**

PSCAD/EMTDC exports its variables in a .out file which contain ten variables plus the time of simulation. If your project has more than 10 variables, another .out file will be created, in order to fit them all. PSCAD/EMTDC also creates a .inf file with the name of the variables and its order in the .out files, once these files does not have a header. It may be boring to check which column belongs to each variable and also open each .out file to import these variables to your python/MATLAB etc project.

**Description**
In order to solve this problem, this package was created: by using it, one can read all of the .out files, storage its variables and also create a .csv file with all the columns and header in a unique file.

The class PSCADVar import all the variables data from the output of both programs simulations and returns it in a object.

PSCADVar reads data from .out: just give the .INF path as argument

__________________

**Requirements**

- **Python 3.8**
- **Packages**: all of them are listed in "requirements.txt"
- To install all of them use: **pip install -r requirements.txt**
Empty file added setup.cfg
Empty file.
27 changes: 27 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from distutils.core import setup
setup(
name = 'ImPSCAD',
packages = ['ImPSCAD'],
version = '0.1',
license='MIT', # Chose a license from here: https://help.github.com/articles/licensing-a-repository
description = 'Import variables from a PSCAD/EMTDC simulation',
author = 'Luis Arthur Novais Haddad',
author_email = 'luis.novais@engenharia.ufjf.br',
url = 'https://github.com/LuisArthurNH',
download_url = 'https://github.com/user/reponame/archive/v_01.tar.gz', # I explain this later on
keywords = ['PSCAD', 'Variables', 'Import','.CSV','python','MATLAB'],
install_requires=[ # I get to this in a second
'validators',
'beautifulsoup4',
],
classifiers=[
'Development Status :: 3 - Alpha', # Chose either "3 - Alpha", "4 - Beta" or "5 - Production/Stable" as the current state of your package
'Intended Audience :: Developers', # Define that your audience are developers
'Topic :: Software Development :: Build Tools',
'License :: OSI Approved :: MIT License', # Again, pick a license
'Programming Language :: Python :: 3', #Specify which pyhton versions that you want to support
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
],
)

0 comments on commit fb0c3a1

Please sign in to comment.