LoadWave Cut data into multiple columns.

Hi Igor!

I have a txt file format that has three columns: Spectrum Number, xdata, ydata and after the data from spectrum1 has finished the next row goes straight into the spectrum2. (I have attached a small part of the text file to illustrate my point, only 2 spectra).

The data I acquire can have as few as 10 consecutive spectra to 120.

I ideally want to load a 2D matrix of waves that such that column0=spectrum1(S1); column1=spectrum2(s2)....columnN(SN) that are interpolated with xdata and keep one column of xdata for reference.

I read the "FReadLine" help topic and I am not entirely sure how to execute it. As using the /T flag the terminator number could be included in previous data and the /N flag the number of characters to read varies depending on data set. I am a terribly bad programmer but learning!


Function LoadAndGraphSpectrum(fileName)
	String fileName // Name of file to load or "" to get dialog
	String pathName // Name of path or "" to get dialog
	String columnInfoStr
	
	// Load the waves and set the local variables.
	LoadWave/A/J/D/O fileName
	if (V_flag==0) // No waves loaded. Perhaps user canceled.
		return -1
	endif
			// Put the names of the three waves into string variables

	String s0, s1, s2
	s0 = StringFromList(0, S_waveNames)
	s1 = StringFromList(1, S_waveNames)
	s2 = StringFromList(2,S_waveNames)

		
	Wave identifier = $s0 // Create wave references.
	Wave wavenumber = $s1
	Wave counts=$s2
	
	Interpolate2   wavenumber, counts
	
	Display counts  // Create a new graph
	// Annotate graph
	Textbox/N=TBFileName/A=LT "Waves loaded from " + S_fileName
	return 0 // Signifies success.
	
End


I have a multiple load function that uses this as its core function...clearly this is very crude and I am at a loss as to how to proceed.

I really appreciate the help i receive on the Igor exchange and look forward to the day I may be able to return the favour!!

Thanks in advance,
Nicola

PS Edited my script to be more specific as for this type of data I will never have more than 3 columns still chopping the waves up is hard and if possible it would be nice once cut to name each column S1, S2 etc
Rennie2SpectraTestdata.txt (21.63 KB)
Hi Nicola,

You could try adding something like

	Variable nSpec=WaveMax(identifier)	//find maximum spectrum
		
	Variable i
		
	For(i=0; i<(nSpec+1); i+=1)
		newName1 = "wn_" + num2str(i)
		newName2 = "c_" + num2str(i)
		
		Duplicate/O wavenumber $newName1
		Wave w2=$newName1
		w2 = (identifier==i) ? wavenumber : NaN
		WaveTransform zapnans w2
		Duplicate/O counts $newName2
		Wave w3=$newName2
		w3 = (identifier==i) ? counts : NaN
		WaveTransform zapnans w3
		If(numpnts(w2)==0)
			Killwaves w2
			Killwaves w3
		Else
		//do what you like here
		Endif
	EndFor


This solution works by filtering your wavenumber and counts waves by the identifier status. It makes a copy of them named according to the identifier. Apologies, it's not well-written but it should help. Your Interpolate2 stuff would go after
Else
.
Thanks sjr51,

I think your way might be a bit more efficient and I have been reading the helptopic on wavetransform to try and better understand what is going on.

I have been working all morning on the code I had initially started and transformed it into this


Function LoadAndGraphSpectrum(fileName)
	String fileName // Name of file to load or "" to get dialog
	String newDF
	
		
	// Load the waves and set the local variables.
	LoadWave/A/J/D/O fileName
	if (V_flag==0) // No waves loaded. Perhaps user canceled.
		return -1
	endif
			// Put the names of the three waves into string variables

	String s0, s1, s2
	s0 = StringFromList(0, S_waveNames)
	s1 = StringFromList(1, S_waveNames)
	s2 = StringFromList(2,S_waveNames)

	Wave identifier = $s0 // Create wave references.
	Wave wavenumber = $s1
	Wave counts=$s2
	
	Variable result=Counting(identifier,0)
	Variable numPoints = numpnts(counts) 	
	Variable numSpectra = numPoints/result 	//number of individual spectra in data set
	make/D/N=(result) Sp
	
	Variable i
	Variable j
	string newName1
	for (i=0;i<numPoints;i+=result)
		for(j=0;j<numSpectra;j+=1)
			newName1 = "c_" + num2str(j)
			Duplicate/O/R=[0+i,result+i] Sp, $newName1
		endfor
	endfor 
	
	Duplicate/O/R=[0,result] wavenumber, wnum

	//Interpolate2 wavenumber, counts
End


so the i loop goes through every point and the j loop goes through the number of spectra in data, i think I will adopt the wavemax function though.

I have a problem with the duplicate in the loop. I seem to create waves with increasing names but I can't seem to extract data to insert in the wave.

Any ideas?

Thanks for your help!

Best,
N

Edit: I can't use the wavemax because the identifier doesn't go up in 1,2,3etc which is annoying!
I think I misunderstood a few things...
1) have you managed to load the three waves (I assumed you had looking at your OP, I'm now not sure)?
2) are the numbers in identifier column all integers? If they are not monotonic it won't matter for the code I wrote.

Edit: in fact I definitely misunderstood, you want a 2D matrix not a bunch of individual waves. Let me know about the above and I'll try to help more.
Hi sjr51,

I'm sorry that I didn't explain myself well. I really appreciate your help though!! =)

1) yes I can load my three original waves (which are there really for a reality check)

I decided to essentially load all the waves separately and concatenate at the end...which i'm sure is not the most efficient way to do this...I finally came up with this code(after cornering a software engineer who had never seen Igor before for help):


Function LoadAndGraphSpectrum(fileName)
	String fileName // Name of file to load or "" to get dialog
//	String newDF
	
		
	// Load the waves and set the local variables.
	LoadWave/A/J/D/O fileName
	if (V_flag==0) // No waves loaded. Perhaps user canceled.
		return -1
	endif
			// Put the names of the three waves into string variables

	String s0, s1, s2
	s0 = StringFromList(0, S_waveNames)
	s1 = StringFromList(1, S_waveNames)
	s2 = StringFromList(2, S_waveNames)

	Wave identifier = $s0 // Create wave references.
	Wave wavenumber = $s1
	Wave counts=$s2
	
	Variable result=Counting(identifier,0)
	Variable numPoints = numpnts(counts) 	
	
	Variable i
	String newName1
	Wave bawbag
	for (i=0;i<numPoints;i+=result)

		newName1 = "c_" + num2str(i)
	
		Duplicate/O/R=[0+i,result-1+i] counts, $newName1
	endfor 
	
	string waves = wavelist ("c_*", ";", "")	
	concatenate waves, '2Dbawbag'
	Duplicate/O/R=[0,result-1] wavenumber, wnum

	//Interpolate2 wavenumber, counts
End


I ideally would like use this as a base function to pass to for a multiload and pass each file in a folder to its own unique datafolder.

This structure is good for my file type but maybe not great for adapting for someone else...but hopefully it can give someone a starting point if wanting to do something similar.

If anyone can add comments for improvements it would be much appreciated.

Best wishes,
N