Med-PC® File Reader

This function reads the data files generated by behavior programs run with the MED-PC® IV software from
Med Associates
. Each data set in a file consists of a header, variables and arrays, that are read into Igor variables and waves.


The data sets are loaded into the data folder MedPC. The header is stored in a global string, the variable values in global variables and the arrays in waves. If more than one data set is found in the file, the variable and wave names are numbered consecutively, starting with 1. The waves and variable names use the following scheme:

MPC_#_$, with # being the consecutive number of different data sets and $ the variable/array letter from the MedPC® program.


Note: Each new file load will erase already existing waves and variables in the MedPC folder, so they need to be sorted and moved into an experiment specific folder structure, before the next file can be loaded.



#pragma rtGlobals=1		// Use modern global access method.
#pragma IgorVersion = 5
#pragma version = 2.3

// This function reads a text data file created by MedPC software (Med Associates) into a data folder 
// called MedPC. Previous loaded data will be erased from this folder. If more than one experiment is
// stored in the file, all of them will be read and the necessary data labels consecutively. 
// MedPC names variables and arrays with a single letter. This reader will store the variables  in 
// global variables, the arrays into waves. 
//
// The "#" in the following description denotes the consecutive number for each experiment in the file. 
// The experiments are counted according to their appearance in the data file.
//
// Strings:
//			MPC_fullFileName:			absolute file name (with full path to file)
//			MPC_fileName:				just the file name without the path
//			MPC_#_header:			all the contents above the data section
//
// Variables:
//			MPC_#_$:					$ is the letter name of the variable in the data file
//
// Waves:
//			MPC_#_$:					$ is the letter name of the array stored in the wave,
//										all array data is stored in the wave.


// ***************************************************
// **********         C O N S T A N T    N A M E S      
// ***************************************************
Strconstant ksMPC_dataFolderName = "MedPC"

Strconstant W_LINEEND = "\r"			// windows line end
Strconstant U_LINEEND = "\n"			// unix line end

// Create a menu item for the file reader
Menu "Macros"
	"Open MedPC file...", MedPCFileReader("", "")
End



// Actual file reader
Function MedPCFileReader(path, fileName)
	String path, fileName
	
	String mpcDF = ksMPC_dataFolderName	 // name of the new data folder to store the loaded data
	String cDF = GetDataFolder(1)		// remember which data folder you are in

	if (DataFolderExists(mpcDF))	
		SetDataFolder mpcDF			// the data folder already exists, so switch to it
		KillStrings /A/Z				// delete the previous variables and waves to have a clean load.
		KillVariables /A/Z
		KillWaves /A/Z
	else
		NewDataFolder /S $mpcDF		// create a new data folder and switch to it.
	endif
	
	SVAR MPC_fullFileName
	SVAR MPC_fileName
	
	if (!SVAR_Exists(MPC_fullFileName))
		String /G MPC_fullFileName = ""
	endif
	if (!SVAR_Exists(MPC_fileName))
		String /G MPC_fileName = ""
	endif
	
	Variable refNum, counter = 0
	String dataPath
	
	PathInfo /S $path
			// use a dialog for the user to choose a file to open and create a reference number
	if (strlen(fileName) == 0)
		if (!V_flag)
			Open /D /R /M="Choose a file" /T="????" refNum
		else
			Open /D /R /M="Choose a file" /T="????" /P=$path refNum
		endif
		if (strlen(S_fileName) == 0)
				// file doesn't exist, so nothing more to do; stop here
			SetDataFolder cDF
			return 0
		endif
	
		MPC_fullFileName = S_fileName	// remember the full file name 
			// now extract just the file name without the path
		MPC_fileName = StringFromList(ItemsInList(MPC_fullFileName, ":") - 1, MPC_fullFileName, ":")
			// now extract just the path to the file, without the filename
		dataPath = RemoveListItem(ItemsInList(MPC_fullFileName, ":") - 1, MPC_fullFileName, ":")
			// create a new path so consecutive file loads all point to the last loaded file
		NewPath /O/Q mpc_lastDataPath, dataPath
			// now open the file with the above created reference number
		Open /R refNum as MPC_fullFileName
	else
		if (!V_flag)
			print "** path " + path + " does not exist. STOPPED!"
			return 0
		endif
		Open /R /P=$path refNum as fileName
		MPC_fullFileName = S_fileName
		MPC_fileName = StringFromList(ItemsInList(MPC_fullFileName, ":") - 1, MPC_fullFileName, ":")		
	endif
	
	if (refNum == 0)
			// something went wrong and the file can not be opened; stop here and print error message
		print "** ERROR: Can not open file."
		MPC_fileName = "wrong file"
		return 0
	endif
	
	Variable headerFlag = 1			// true (1) if currently in header section, false (0) when in data section
	Variable experimentNum = 0	// experiment number, when more than 1 in the file.
	Variable hasComment = 0
	
	String varName = ""
	String theHeaderContent = ""
	String theLine = ""
	String theWaveList = ""
	String theComment = ""
	String theNote = ""
	
	do
		// process the file reading line by line
		FReadLine refNum, theLine
		if (strlen(theLine) == 0)
			// reached EOF (end of file) so stop loop
			break
		endif
		if ((cmpstr(theLine, W_LINEEND) == 0) || cmpstr(theLine, U_LINEEND) == 0)
			// three empty lines separate different experiments
			headerFlag = 1
			hasComment = 0
			theComment = ""
			theWaveList = ""
			counter += 1
			continue
		endif
		if (headerFlag)		// analyse header
			if (strsearch(theLine, "Start Date: ", 0) == 0)
				// each header starts with the Start Date, so increase the experiment number
				experimentNum += 1
			endif
			if (counter > 0 && strlen(theLine) > 2)
				theLine = ReplaceString(": ", theLine[0, strlen(theLine) - 2], "=")
				theHeaderContent += theLine + "\n"
			endif
			if (strsearch(theLine, "MSN=", 0) == 0)
				// MSN is the last line of the header, so finish it up.
				theHeaderContent= "file=" + MPC_fileName + "\n" + theHeaderContent
				headerFlag = 0
				varName = "MPC_" + num2str(experimentNum) + "_header"
				SVAR theHeader = $varName
				if (!SVAR_Exists(theHeader))
					String /G $varName = theHeaderContent
				else
					theHeader = theHeaderContent
				endif
				theHeaderContent = ""
			endif
		else					// data section
			theLine = theLine[0, strlen(theLine) - 2]
			SVAR theHeader = $("MPC_" + num2str(experimentNum) + "_header")
			
			if (cmpstr(theLine[0,0], "\\") == 0)
				if (!SVAR_Exists(theHeader))
					String /G $("MPC_" + num2str(experimentNum) + "_header")
					SVAR theHeader = $("MPC_" + num2str(experimentNum) + "_header")
				endif
				theComment += theLine[1, strlen(theLine) - 1] + ", "
				hasComment = 1
			endif
			
			Variable listItems = ItemsInList(theLine, ":")
			if (listItems == 1 && strlen(StringFromList(0, theLine, ":")) == 1)
				// only single letter array variables should match this condition
				varName = "MPC_" + num2str(experimentNum) + "_" + theLine[0,0]				
				Make /N=0 /O $varName
				Wave curArray = $varName
				theWaveList = AddListItem(varName, theWaveList)
				if (SVAR_Exists(theHeader))
					Note /K curArray, theHeader
				endif
			endif
			if (listItems == 2 && numtype(str2num(StringFromList(0, theLine, ":"))) == 0)
					// first separate the row number from the data
				Variable firstIndex = str2num(StringFromList(0, theLine, ":"))
					// now figure out how many data columns we have
				String theColumns = StringFromList(1, theLine, ":")
					// replace every space with a ; then just move the non-empty list items into a new list
				theColumns = ReplaceString(" ", theColumns, ";")
				Variable index = 0
				String dataPoints = ""
				for (index = 0; index < ItemsInList(theColumns); index += 1)
					String theData = StringFromList(index, theColumns)
					if (cmpstr(theData, "") != 0)
						dataPoints = AddListItem(theData, dataPoints, ";", ItemsInList(dataPoints))
					endif
				endfor
				Variable numColumns = ItemsInList(dataPoints)
				for (index = 0; index < ItemsInList(dataPoints); index += 1)
					curArray[numpnts(curArray)] = {str2num(StringFromList(index, dataPoints))}
				endfor
			endif
			if (listItems == 2 && numtype(str2num(StringFromList(0, theLine, ":"))) == 2)
				// is a variable, just stick it into a global
				varName = "MPC_" + num2str(experimentNum) + "_" + StringFromList(0, theLine, ":")
				NVAR theVar = $varName
				if (!NVAR_Exists(theVar))
					Variable /G $varName = str2num(StringFromList(1, theLine, ":"))
				else
					theVar = str2num(StringFromList(1, theLine, ":"))
				endif
			endif
		endif
		counter += 1
		Variable comments = 0
		if (hasComment)
			// in case we use keywords and the Igor default list separator ";", remove any spaces between them
			theComment = ReplaceString(" ; ", theComment, ";")
			theComment = ReplaceString("; ", theComment, ";")
			theComment = ReplaceString(" ;", theComment, ";")
			theComment = ReplaceString(": ", theComment, ":")
			theHeader += "comment=" + theComment + "\n"
			for (comments = 0; comments < ItemsInList(theWaveList); comments += 1)
				String theWaveName = StringFromList(comments, theWaveList)
				Note /K $theWaveName, theHeader
			endfor
		endif
	while(1)
	Close refNum
	SetDataFolder cDF
End

Forum

Support

Gallery

Igor Pro 10

Learn More

Igor XOP Toolkit

Learn More

Igor NIDAQ Tools MX

Learn More