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 8

Learn More

Igor XOP Toolkit

Learn More

Igor NIDAQ Tools MX

Learn More