Extracting the date and time from the first lines of a .txt file
LaMP
Hello (again!),
I have a text file that contains several lines of text (describing the contents of each column). The second line of text includes the date and time indicating the "start time" of the data included in this file.
The first 'data' column represents the number of seconds passed since the file "start time".
Files are attached for example.I would like to know if it is possible to create a timeW using this data (Start time + seconds passed). It would also be useful to be able to extract the threshold number (in the example above 2.595) as a constant number in a wave having the same length of the file.
Thank you again :)
Hi,
Here is something to start with, it opens the file for reading and looks for the line that contains "start" and it parses that line to get the year, month, day, hour, minute, and seconds as integer variables. It then gets the seconds count for that day and adds on the time converted to seconds. In the end it returns a single variable with the seconds at the start time. If you are going to automate you will probably want to pass some file sting reference.
variable refnum,year,month,day, hour,minute,second, startTime
string buffer
open/r refnum
do
freadline refnum, buffer
if (stringmatch(buffer,"*start*"))
print buffer
sscanf buffer, " start: %i-%i-%i %i:%i:%i",year,month,day,hour,minute,second
print day, month, year, hour, minute, second
starttime = date2secs(year,month,day) +hour*3600+minute*60 + second
break
endif
while(strlen(buffer)>0)
close refnum
return starttime
end
Andy
March 7, 2023 at 05:55 pm - Permalink
Hi Andy,
Thanks very much.
This reads out the date and time very well. But how can I integrate this into my matrix that I am loading? I am currently adapting some code to work with this new data set? As I have several (hundred) different text files of different format to load.
On a side note: I am getting an error when using this code " Can't convert a text wave to or from another type." I don't understand yet as I can load it without any trouble using the load/general text option in the tool bar.
// Prompts to select folder into which data is loaded
String PathToFldr="",CtrlName="",PromptStr="Select folder to load PINE data into:",CurrentFldr=getdatafolder(1) // variables for Browse4Folder
Browse4Folder(PathToFldr,CtrlName,PromptStr,CurrentFldr) // prompts user to select an experiment
// Get folder with data in it
NewPath/M="Select folder containing newpine data:"/O/Q pathname // prompts user to select path to data folder
PathInfo pathname
// Abort if cancel is pressed
If(V_flag==0)
Abort "proceedure cancelled"
EndIf
// Make matrix for opc data
Make/o/n=(0,22) newPINEDataMatrix
// Strings and Variables
Variable numfolders,n, subdirs, numfiles, filenum, refnum // variables
String folderlist, filename, name, currentfolder // strings
// Counts number of files in folder
NumFiles=ItemsInList(IndexedFile(pathname,-1,".txt")) // # files in folder , specify extensions e.g. ".txt"
For(filenum=0;filenum<numfiles;filenum+=1) // loops through each file name
filename=s_path+StringFromList(filenum,IndexedFile(pathname,-1,".txt"))
If(Stringmatch(FileName,"*test*")==1)
Open /R/P=pathname/Z refNum as filename // open
FStatus refNum // check there is data in file
If(V_logEOF>1) // specify minimum file size to load e.g. >10bytes
Load_newPINEdATAFile(filename, refnum)
Wave Temp_newPINEDataMatrix0
// add loaded waves to loaded data
int numRowsAlreadyLoaded = DimSize(newPINEDataMatrix,0)
int numNewRowsToAppend = DimSize(Temp_newPINEDataMatrix0,0)
int numNewColumns = DimSize(Temp_newPINEDataMatrix0,1) // *** This is new ***
InsertPoints numRowsAlreadyLoaded,numNewRowsToAppend,newPINEDataMatrix
newPINEDataMatrix[numRowsAlreadyLoaded,*][0,numNewColumns-1]=Temp_newPINEDataMatrix0[p-numRowsAlreadyLoaded][q]
Endif
Endif
Endfor
END
Function Load_newPINEDataFile(filename, refnum) // load single opc_spd file
String filename
Variable refnum
print "Loading: " + filename
LoadWave/D/G/W/v={"\t,","",0,0}/K=1/L={0,0,0,0,0}/O/M/N=temp_newpineDatamatrix/Q filename
//LoadWave/J/D/W/ENCG=3/v={"\t","\ ",0,0}/K=0/L={6,7,0,0,0}/R={English,2,2,2,2,"Year-Month-DayOfMonth",40}/O/M/N=temp_newpineDatamatrix/Q filename
end
March 8, 2023 at 06:44 am - Permalink
Hi,
If the file you are loading is the same as the example txt files you provided, then I think the L flag needs to be modified. Currently it is starting at the first line which is part of the header and it is determined to be text. The data appears to start on line 20 (zero based counting). I used
To successfully load the example file. Note if the header rows vary from file to file you will need to determine where the data starts.
Andy
March 8, 2023 at 07:12 am - Permalink
Hmmm.... When downloaded on my Macintosh, the line endings get stripped out...
On Windows I get very long lines; the line with the column labels on it includes what looks like data:
Do others get something else?
March 8, 2023 at 09:37 am - Permalink
Hi John,
Yes there is a lot of columns but I dont need them (at least for the moment). I am interested in the data in the columns CN_NB and n_NB and the t_rel (creating a date time wave).
Thanks
March 8, 2023 at 01:12 pm - Permalink
So regarding the error above, answered by ANDY. I used a different piece of code snippet and it worked. I will check why I was getting this error.
String filename
Variable refnum
print "Loading: " + filename
//LoadWave/J/W/ENCG=3/v={"\t","\ ",0,0}/K=0/L={5,6,0,0,0}/O/M/N=temp_PINEtempscanmatrix/Q filename
LoadWave/J/D/W/ENCG=3/v={"\t","\ ",0,0}/K=0/L={8,9,0,0,0}/R={English,2,2,2,2,"Year-Month-DayOfMonth",40}/O/M/N=temp_PINEtempscanmatrix/Q filename
end
However, I would still like to read the start time and calculate a time wave from the seconds since start. The read_return function works well but I am unsure how/where I should integrate this into the code..
March 8, 2023 at 01:37 pm - Permalink
Hi,
I will assume that one of your columns is the relative time stamp, t_rel. The constraint within Igor is that the data modeling type must be the same for all columns in a matrix. This means if you want to create a column with the full date/time stamp and have Igor use it as such all the other columns will be considered date/time data types as well. Probably not what you want. This behavior is similar to arrays in numpy in Python. Pandas Dataframes in Python allow for different data types for each columns. I have used labels frequently to fake a text column within a numeric wave, but that is another story.
One suggestion assuming that the t_rel column contains the number of seconds from start time. I would create a new wave, realTime, with the same length of rows as your matrix and set its values
realTime[]= startTime + DataMatrix[p][%t_rel]
I would the use setscale to set to date time with
SetScale d 0,0,"dat", realTime
When plotting use the realTime wave as the x.
Andy
March 8, 2023 at 01:59 pm - Permalink
Hello Andy,
The read_return() function just reads out the date from the file being loaded. However I have a number of files to load, each having a different start time.
Would it be possible to load them into a wave and do what you suggested above as a separate function?
Thanks
March 9, 2023 at 05:36 am - Permalink
Hi,
There are a variety of ways to handle this depending on your work flow and final objective. The function returns a number which is the seconds from 1/1/1904. You can store in a variety of places depending on what happens next. Options include:
1. After a data file is loaded a separate wave with a similar file name perhaps with "_time" suffix is created that contains the full date/time data.
2. A master wave that holds the starting time that is then used latter in a function to dynamically create the time wave.
3. You could store in a wave note as a key value pair that is later read.
It really depends on your ultimate work flow. For example I often have to process multiple data files to extract calculated results such as peak position, slope, ..... In those cases I create a workflow that does all the loading and calculations on a single data set. I then append the net results to a separate wave with the sample name as the row label. When I run through I overwrite the individual data files since I am interested only in the calculated results.
If however you are interested in comparing run to run on a graph then I might load the data with sample Id as matrix name and a matching time wave with a name linked to the data matrix wave.
Andy
March 9, 2023 at 07:37 am - Permalink
Hi Andy,
Thank you for your response. I am more interested in the later option, to compare the data (particle concentrations) as it varies with time, but also to have the posssibilty to compare the data with other parameters. For this reason I need a time stamp that can be used for eventually averaging concentrations.
Thanks
March 9, 2023 at 08:03 am - Permalink