How to create a repeating pattern of a defined time on a graph?

Hello all,

I am doing electrophysiological experiments in which a repetitive stimulus is applied over a defined time window within a larger sampling period; specifically:

A single sweep is 5 seconds long. Within that 5 seconds, a repetitive stimulus is applied from t=3 to t=4 seconds. The stimulus is pulsed light at 10 Hz, where each light pulse lasts 20ms. What I would like to do is to have each of the light stimuli graphically represented in a temporally accurate way... in other words, to have lines whose x values equal 20ms, and which start at the time points when they were actually applied (i.e. 3.0, 3.1, 3.2, etc), and to be able to include these lines in a graph where the actual recording data is shown.

I've been doing this manually by making separate lines for each stimulus and aligning them... but it is very laborious and I'm guessing there must be an automated way to do this... any advice would be very much appreciated!!

Thank you,
Todd

I think this should do it or at least get you started:

// Makes a stimulus pattern.
// Example:
//  MakeStimulusPattern(3, 4, 10, .02, 1, "MyStimulus")
//  Display MyStimulus_y vs MyStimulus_x
Function MakeStimulusPattern(startTime, endTime, frequency, onTime, pulseLevel, patternName)
    Variable startTime      // e.g., 3 for 3 seconds
    Variable endTime        // e.g., 4 for 4 seconds
    Variable frequency      // e.g., 10 for 10 Hz
    Variable onTime         // e.g., .02 for 20 ms
    Variable pulseLevel     // e.g., 1 for lines at Y=1
    String patternName      // e.g., "MyStimulus"
   
    Variable totalTime = endTime - startTime
    Variable numPulses = totalTime * frequency
    Variable timeBetweenPulses = 1 / frequency
   
    // We need end points for each pulse and a blank in between pulses
    Variable numPoints = 3*numPulses
   
    String xName = patternName + "_x"
    String yName = patternName + "_y"
    Make/O/N=(numPoints) $xName, $yName
    Wave xw=$xName, yw=$yName   // Create wave references
   
    Variable i
    for(i=0; i<numPulses; i+=1)
        xw[i*3] = startTime + i*timeBetweenPulses
        xw[i*3+1] = xw[i*3] + onTime
        xw[i*3+2] = NaN     // Blank to separate pulses
       
        yw[i*3] = pulseLevel
        yw[i*3+1] = pulseLevel
        yw[i*3+2] = NaN     // Blank to separate pulses
    endfor
End


Paste into the procedure window and execute the example commands shown in the comments.
Thank you very much for writing out a detailed procedure, I really appreciate your time. One thing I am not clear on is how to execute the procedure that you wrote. I did the following:

->Windows -> Procedure window -> Procedure Window, and then pasted your text into the window. But after that I got stuck.. am I supposed to 'execute' that procedure while a graph is open? If so, how do I do that? Also, is this going to draw lines of defined width and placement in the graph which I can modify after they are drawn (change color, line thickness, etc..)?

Sorry if these are mundane questions but I have not used procedures before...

Thank you again for your help -
Todd
You're nearly there. Press the compile button in the lower left of the procedure window or use the Compile Porcedures option in the Macros menu. After the procedures have been compiled, paste the two lines given in Howard's snippet to your command window, but without the comment signs (//), i.e.

MakeStimulusPattern(3, 4, 10, .02, 1, "MyStimulus")
Display MyStimulus_y vs MyStimulus_x


The first line calls ("executes") Howard's function, which just calculates a new pair of data waves called MyStimulus_x and MyStimulus_y (since you have called the function with the argument "MyStimulus").

The second line displays the data in a new graph window. You could have the same result by choosing "New Graph" form the Window menu and selecting these waves manually. Naturally, you have all the ways to adapt the style of the stimulus trace as you have for your experimental data.

If you want to plot the stimulus wave in the same graph as your experimental data, you can either use the menus or execute the following line from the command window (your experimental graph being in front):
AppendToGraph MyStimulus_y vs MyStimulus_x

For further work with the procedure window and programming, it would be best if you consulted the manual or did the tutorial...
Quote:
But after that I got stuck.. am I supposed to 'execute' that procedure while a graph is open?


Please do the first half of the Igor Guided Tour. You can find it by choosing Help->Getting Started or in Volume I of the Igor PDF manual.

Doing the Guided Tour, or at least the first half of it, is essential for using Igor.
Thank you very much Wolfgang and Howard, I was able to execute the procedure and saw exactly what I was looking for. One last thing I wanted to ask is if there is a straightforward way to convert the procedure output from seconds to milliseconds? Most of my data is in milliseconds and when I tried to put both waves in a single graph, I got the stimulus pattern running from 3-4 ms, not 3-4 seconds.

I took a look at the procedure and tried to make a few changes (e.g. changing the Variable timeBetweenPulses = 1 / frequency to 1000/frequency) but did not get the desired output.. could you tell me what needs to be amended?
Here is a revised version that uses milliseconds:
// Makes a stimulus pattern.
// Example:
//  MakeStimulusPattern(3000, 4000, 10, 20, 1, "MyStimulus")
//  Display MyStimulus_y vs MyStimulus_x
Function MakeStimulusPattern(startTime, endTime, frequency, onTime, pulseLevel, patternName)
    Variable startTime      // e.g., 3000 for 3000 milliseconds
    Variable endTime        // e.g., 4000 for 4000 milliseconds
    Variable frequency      // e.g., 10 for 10 Hz
    Variable onTime         // e.g., 20 for 20 ms
    Variable pulseLevel     // e.g., 1 for lines at Y=1
    String patternName      // e.g., "MyStimulus"
   
    Variable totalTime = endTime - startTime
    Variable millisecondsBetweenPulses = 1000 / frequency
    Variable numPulses = totalTime / millisecondsBetweenPulses
   
    // We need end points for each pulse and a blank in between pulses
    Variable numPoints = 3*numPulses
   
    String xName = patternName + "_x"
    String yName = patternName + "_y"
    Make/O/N=(numPoints) $xName, $yName
    Wave xw=$xName, yw=$yName   // Create wave references
   
    Variable i
    for(i=0; i<numPulses; i+=1)
        xw[i*3] = startTime + i*millisecondsBetweenPulses
        xw[i*3+1] = xw[i*3] + onTime
        xw[i*3+2] = NaN     // Blank to separate pulses
       
        yw[i*3] = pulseLevel
        yw[i*3+1] = pulseLevel
        yw[i*3+2] = NaN     // Blank to separate pulses
    endfor
End

Thank you very much Howard, the revised procedure works great and generates exactly what I need.. I really appreciate your help!