Skip to content

Commit

Permalink
Merge pull request #5 from minhhaiphys/master
Browse files Browse the repository at this point in the history
Add kwarg delimiter to TextWriter
  • Loading branch information
cmars committed Jan 2, 2018
2 parents c374f81 + 036d188 commit e0fc4f9
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 6 deletions.
1 change: 1 addition & 0 deletions README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ record "events" in callback functions
Refer to the provided command line scripts for ideas on how to use PySTDF:

stdf2text, convert STDF to '|' delimited text format.
stdf2excel, convert STDF to MS Excel.
stdf_slice, an example of how to seek to a specific record offset in the STDF.

I have also included a very basic STDF viewer GUI, StdfExplorer. I have plans
Expand Down
86 changes: 86 additions & 0 deletions pystdf/Importer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#
# PySTDF - The Pythonic STDF Parser
# Copyright (C) 2006 Casey Marshall
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# Modified: 2017 Minh-Hai Nguyen
#

import numpy as np
import pandas as pd
from pystdf.IO import Parser
from pystdf.Writers import TextWriter

class MemoryWriter:
def __init__(self):
self.data = []
def after_send(self, dataSource, data):
self.data.append(data)
def write(self,line):
self.data.append(line)
def flush(self):
pass # Do nothing

def ImportSTDF(fname):
with open(fname,'rb') as fin:
p = Parser(inp=fin)
storage = MemoryWriter()
p.addSink(storage)
p.parse()
return storage.data

def STDF2Text(fname,delimiter='|'):
""" Convert STDF to a list of text representation
"""
with open(fname,'rb') as fin:
p = Parser(inp=fin)
storage = MemoryWriter()
p.addSink(TextWriter(storage,delimiter=delimiter))
p.parse()
return storage.data
return None

def STDF2Dict(fname):
""" Convert STDF to a list of dictionary objects
"""
data = ImportSTDF(fname)
data_out = []
for datum in data:
datum_out = {}
RecType = datum[0].__class__.__name__.upper()
datum_out['RecType'] = RecType
for k,v in zip(datum[0].fieldMap,datum[1]):
datum_out[k[0]] = v
data_out.append(datum_out)
return data_out

def STDF2DataFrame(fname):
""" Convert STDF to a dictionary of DataFrame objects
"""
data = ImportSTDF(fname)
BigTable = {}
for datum in data:
RecType = datum[0].__class__.__name__.upper()
if RecType not in BigTable.keys():
BigTable[RecType] = {}
Rec = BigTable[RecType]
for k,v in zip(datum[0].fieldMap,datum[1]):
if k[0] not in Rec.keys():
Rec[k[0]] = []
Rec[k[0]].append(v)
for k,v in BigTable.items():
BigTable[k] = pd.DataFrame(v)
return BigTable
12 changes: 6 additions & 6 deletions pystdf/Writers.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,17 @@ def format_by_type(value, field_type):
return str(value)

class TextWriter:
def __init__(self, stream=sys.stdout, delimiter='|'):
self.stream = stream
self.delimiter = delimiter

@staticmethod
def text_format(rectype, field_index, value):
field_type = rectype.fieldStdfTypes[field_index]
if value is None:
return ""
elif rectype is V4.gdr:
return '|'.join([str(v) for v in value])
return self.delimiter.join([str(v) for v in value])
elif field_type[0] == 'k': # An Array of some other type
return ','.join([format_by_type(v, field_type[2:]) for v in value])
elif rectype is V4.mir or rectype is V4.mrr:
Expand All @@ -50,12 +53,9 @@ def text_format(rectype, field_index, value):
else:
return str(value)

def __init__(self, stream=sys.stdout):
self.stream = stream

def after_send(self, dataSource, data):
line = '%s:%s%s' % (data[0].__class__.__name__.upper(),
'|'.join([self.text_format(data[0], i, val) for i, val in enumerate(data[1])]), '\n')
line = '%s%s%s\n' % (data[0].__class__.__name__.upper(),self.delimiter,
self.delimiter.join([self.text_format(data[0], i, val) for i, val in enumerate(data[1])]))
self.stream.write(line)

def after_complete(self, dataSource):
Expand Down
53 changes: 53 additions & 0 deletions scripts/stdf2excel
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/usr/bin/env python
#
# PySTDF - The Pythonic STDF Parser
# Copyright (C) 2006 Casey Marshall
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# Modified: 2017 Minh-Hai Nguyen
#
import sys, os
from pystdf.Importer import STDF2DataFrame
import pystdf.V4


def toExcel(fname,tables):
""" Export the tables from toTables to Excel
"""
writer = pd.ExcelWriter(fname)
for k,v in tables.items():
# Make sure the order of columns complies the specs
record = [r for r in V4.records if r.__class__.__name__.upper()==k]
if len(record)==0:
print("Ignore exporting table %s: No such record type exists." %k)
else:
columns = [field[0] for field in record[0].fieldMap]
v.to_excel(writer,sheet_name=k,columns=columns,index=False,na_rep="N/A")
writer.save()

if __name__=="__main__":
if len(sys.argv)==1:
print("Usage: %s <stdf file>" % (sys.argv[0]))
else:
fin = sys.argv[1]
if len(sys.argv)>2:
fout = sys.argv[2]
else:
fout = fin[:fin.rfind('.')]+".xlsx"
print("Importing %s" %fin)
dfs= STDF2DataFrame(fin)
print("Exporting to %s" %fout)
toExcel(fout,dfs)

0 comments on commit e0fc4f9

Please sign in to comment.