Source code for stlabutils.newfile
"""Method for opening a new file for writing
This module contains a single method used for creating a new datafile. This method
handles timestamping the measurement folder, keeping track of the index of the measurement
(if desired) and makes backup copies of the previously run scripts for reference.
"""
import datetime
import os
import shutil
import re
from . import getgitid
# Creates new measurement folder using prefix + datetime + idstring.
# If colnames (array of column names) is included, the title line is written
# Also copies main script file to measurement folder
[docs]def newfile(prefix,
idstring,
colnames=None,
mypath='./',
usedate=True,
usefolder=True,
autoindex=False,
return_folder_name=False,
git_id=True):
"""Creates a new file for storing data.
By default will create a folder (at the location of the running script) with a new file open for writing
and a copy of the script the function was called from. The naming scheme for the folder is :code:`<prefix>_yy_mm_dd_HH.MM.SS_<idstring>`.
The file is named the same with a ".dat" extension.
Generally, if using default options, overwriting an existing file should not happen (date and time will never be exactly equal).
However, if the desired filename already exists, this method will overwrite the old file.
Parameters
----------
prefix : str
A string to be placed in front of the timestamp in the filename. Can be blank or None but must be specified
idstring : str
A string to be placed behind the timestamp. Can also be blank or None but must be specified
colnames : list of str, optional
Array-like containing column titles for data. This will be written in the first line of the file delimited by ', '.
As an example, if colnames = ['abc', 'def', 'ghi'], the first line in the file will be :code:`\"# abc, def, ghi\\n\"`. By default is left blank
mypath : str, optional
Path for folder (or file) creation if pwd is not the desired path. By default it is pwd.
usedate : bool, optional
Boolean to include timestamp. If False, the timestamp is excluded from the file/folder name. True by default
usefolder : bool, optional
If set to False the file will be opened at the specified location with the usual naming but with no
subfolder and no copy will be made of the running script. True by default
autoindex : bool, optional
Specifies if indexing of successively opened files is desired. Will add a running index to the prefix of the newly created file/folder.
This will be incremented by 1 for each new file with the same prefix. If no files are found with the same prefix, it creates the
first file name <prefix>1_yy_mm_dd_HH.MM.SS_<idstring>. Successive files will be named <prefix><idx>_yy_mm_dd_HH.MM.SS_<idstring>.
Is False by default.
git_id : bool, optional
Boolean to query and save the git id of stlab
Returns
-------
myfile : _io.TextIOWrapper
Open file handle for writing
"""
import __main__
if hasattr(__main__, '__file__'):
mainfile = __main__.__file__
else:
mainfile = None
print(mainfile)
mytime = datetime.datetime.now()
datecode = '%s' % mytime.year + '_' + (
'%s' % mytime.month).zfill(2) + '_' + ('%s' % mytime.day).zfill(2)
timecode = ('%s' % mytime.hour).zfill(2) + '.' + (
'%s' % mytime.minute).zfill(2) + '.' + ('%s' % mytime.second).zfill(2)
# Autoindexing... Prefix is followed by an incremental index.
# Looks for already present files/folders with the same prefix and indexes and creates the next index.
# If none are found, starts with the first.
if autoindex:
if (prefix == '' or prefix == None):
raise ValueError('No prefix given for autoindexing')
namelist = [name for name in os.listdir(mypath)]
idxs = []
pattern = '^' + prefix + '\\d+$'
pattern = re.compile(pattern)
for name in namelist:
name = name.split('_')[0]
match = pattern.match(name)
if match:
nn = int(name[len(prefix):])
idxs.append(nn)
if idxs:
prefix = prefix + str(max(idxs) + 1)
else:
prefix = prefix + '1'
if usedate:
foldername = prefix + '_' + datecode + '_' + timecode + '_' + idstring
else:
foldername = prefix + '_' + idstring
#Check if prefix or idstring are blank and remove unnecessary underscores
if (idstring == '' or idstring == None):
foldername = foldername[:-1]
if (prefix == '' or prefix == None):
foldername = foldername[1:]
if len(foldername) == 0:
raise ValueError(
'No name given... Add at least a prefix or idstring or date')
filename = foldername + '.dat'
if usefolder:
fullfoldername = os.path.normpath(mypath + '/' + foldername)
fullfilename = os.path.normpath(mypath + '/' + foldername + '/' +
filename)
else:
fullfoldername = os.path.normpath(mypath + '/')
fullfilename = os.path.normpath(mypath + '/' + filename)
print(fullfoldername)
print(fullfilename)
if not os.path.exists(fullfoldername):
os.makedirs(fullfoldername)
print('Measurement Name: ', foldername)
if mainfile != None and usefolder:
scriptname = os.path.basename(mainfile)
shutil.copyfile(mainfile,
os.path.normpath(fullfoldername + '/' + scriptname))
myfile = open(fullfilename, 'w')
if colnames is not None:
varline = '#' + ', '.join(colnames) + '\n'
myfile.write(varline)
if git_id:
try:
getgitid.get_gitid(myfile)
except subprocess.CalledProcessError as e:
print("##################\nget_gitid failed:\n", e.output)
except FileNotFoundError:
print("##################\nget_gitid failed:\nYour stlab(utils) is most likely not a git repo but was downloaded")
if return_folder_name:
return myfile, fullfoldername
else:
return myfile