@stim_analyze & modern version

Dear all,

I would like to use @stim_analyze or @stim_analyze_modern to iteratively create & evaluate (via 3dDeconvolve -nodata) random event-related timing parameters in order to maximize efficiency & power of our design. I have 2 questions – 1) what are the differences between the two scripts? Am I correct to think the only differences are in the make_random_timing.py arguments, with the _modern version taking advantage of the timing classes functionality? and 2) in our experiments we use a MION contrast agent that significantly alters the HRF by lengthening time to return to baseline (recovery is on the order of 30-40, rather than 10-20 seconds). How can I incorporate this aspect of the response function into the pipeline?

thanks much.
best,
Geena

Hi Geena,

Yes, the modern one just applies the modern version of make_random_timing.py.

I would think that in your case, the modern version might still be reasonable to apply, as you would be able to specify the min/mean/max of the ITIs, which would presumably tend to be long.

The created 3dDeconvolve script will use BLOCK, but you might just pipe that through a “sed” command to convert BLOCK(A,1) (for whichever A) to the appropriate MION response function.

Try setting that up as you see fit, and then I can comment more directly on the commands you are trying. If you also post the -stim_times lines of the 3dDeconvolve command, along with your preferred MION function, I can suggest how to convert it.

  • rick

Hi Rick,
thanks much ! I am attaching the stim_analyze_modern script at the bottom, with my edits for clarity. from the 3dDeconvolve cmd –

3dDeconvolve
-nodata 1680 2.000
-polort 2
-concat ‘1D: 0 168 336 504 672 840 1008 1176 1344 1512’
-num_stimts 1
-stim_times 1 movemouth.0004_01_mouth.1D GAM
-stim_label 1 mouth
-x1D X.movemouth.0004.xmat.1D

from the 3dDecon help, I see that MION(d) could be used instead of GAM (although you mentioned the default was BLOCK?) – In our experiment, these events are motor outputs of the participant, that last for <1 second. My questions are, 1) is it still appropriate to use the MION(d) if d is so short, or would it be more appropriate to convolve the MION response with the event-times only? 2) our lab’s “preferred” mion fxn is piped through fsfast, which takes additional input parameters (ie., mion response is a modified gamma fxn with delta=0, tau=8, exponent=0.3) – I’m wondering if these are specified as default values somewhere in AFNI, or how it is handled.

thanks much.
best,
Geena


#!/bin/tcsh

try to find reasonable random event related timing given the experimental

parameters

---------------------------------------------------------------------------

some experiment parameters (most can be inserted directly into the

make_random_timing.py command)

---------------------------------------------------------------------------

execution parameters

set iterations = 10000 # number of iterations to compare
set seed = 1234567 # initial random seed
set outdir = stim_results # directory that all results are under
set LCfile = NSD_sums # file to store norm. std. dev. sums in

set pattern = LC # search pattern for LC[0], say

set pattern = ‘norm. std.’ # search pattern for normalized stdev vals

===========================================================================

start the work

===========================================================================

------------------------------------------------------------

recreate $outdir each time

if ( -d $outdir ) then
echo “** removing output directory, $outdir …”
\rm -fr $outdir
endif

echo “++ creating output directory, $outdir …”
mkdir $outdir
if ( $status ) then
echo “failure, cannot create output directory, $outdir”
exit
endif

move into the output directory and begin work

cd $outdir

create empty LC file

echo -n “” > $LCfile

echo -n “iteration (of $iterations): 0000”

------------------------------------------------------------

run the test many times

foreach iter (count -digits 4 1 $iterations)

    # make some other random seed

    @ seed = $seed + 1


    # create randomly ordered stimulus timing files
    # (consider: -tr_locked -save_3dd_cmd tempfile)

make_random_timing.py -num_runs 10 -run_time 336
-tr 2
-pre_stim_rest 10 -post_stim_rest 40
-rand_post_stim_rest no
-add_timing_class stim 1
-add_timing_class rest 2 -1 45 dist=decay_fixed
-add_stim_class mouth 20 stim rest
-prefix threat_app.$iter
-write_event_list events.$iter.txt
-show_timing_stats
-seed $seed
-save_3dd_cmd cmd.3dd.$iter.txt >& out.mrt.$iter

    # consider: sed 's/GAM/"TENT(0,15,7)"/' tempfile > cmd.3dd.$iter
    #           rm -f tempfile

    # now evaluate the stimulus timings

    tcsh cmd.3dd.$iter.txt >& out.3dD.$iter

    # save the sum of the 3 LC values
    set nums = ( `awk -F= '/'"$pattern"'/ {print $2}' out.3dD.${iter}` )

    # make a quick ccalc command
    set sstr = $nums[1]
    foreach num ( $nums[2-] )
        set sstr = "$sstr + $num"
    end
    set num_sum = `ccalc -expr "$sstr"`

    echo -n "$num_sum = $sstr : " >> $LCfile
    echo    "iteration $iter, seed $seed"                  >> $LCfile

    echo -n "\b\b\b\b$iter"

end

echo “”
echo “done, results are in ‘$outdir’, LC sums are in ‘$LCfile’”
echo consider the command: “sort -n $outdir/$LCfile | head -1”

Hi Geena,

Since make_random_timing.py does not currently have the ability to control the basis function (aside from the length of the stimulus, which dictates GAM vs BLOCK), you could change GAM to MION(1) via sed or something, as in:

sed "s/GAM/'MION(1)'/g" cmd.3dd.OLD.txt > cmd.3dd.NEW.txt

That would change any instances of GAM into ‘MION(1)’ in the “OLD” script, and save it as a “NEW” version.

I can look into how straightforward it would be to add such a thing directly into make_random_timing.py, too.

  • rick

Okay, you can now specify the basis as a parameter to the timing class, e.g.

-add_timing_class stim 1 1 1 'basis=MION(1)'

Note that when specifying parameters, you need to specify min, mean and max, even if they are identical.

This should be available after the next build, which should be available in the morning, at the latest.

Please let me know if this seems reasonable to you, and how it goes.

  • rick

Hi Rick,

thanks so much, this is super helpful, I will try tomorrow AM & report back. One follow-up question – can you say a bit more about the form of the MION function as built in AFNI? I want to make sure I am running this optimization procedure with the exact same basis function we will use during analysis. Normally, for us MION is a gamma function = (((t-delta)/tau).^alpha) .* exp(-(t-delta)/tau), with delta = 0; tau = 8000; alpha = 0.3; dt = 1 ms. Are these also the parameters inside AFNI’s “MION” ? I was not clear from the 3dDeconvolve -help output.

thanks again!
best,
G

Hi Geena,

Those do not seem like the same parameters, according to ‘3dDeconvovle -help’. is part of the section with details, including a publication reference. You might want to locate this text and review it in more detail.

     'MION(d)'     = 1 parameter block stimulus of duration 'd',       
                     intended to model the response of MION.           
                     The zero-duration impulse response 'MION(0)' is   
                       h(t) = 16.4486 * ( -0.184/ 1.5 * exp(-t/ 1.5)   
                                          +0.330/ 4.5 * exp(-t/ 4.5)   
                                          +0.670/13.5 * exp(-t/13.5) ) 
                     which is adapted from the paper                   
                      FP Leite, et al. NeuroImage 16:283-294 (2002)    
                      http://dx.doi.org/10.1006/nimg.2002.1110         
                  ** Note that this is a positive function, but MION   
                     produces a negative response to activation, so the
                     beta and t-statistic for MION are usually negative. 

For plotting the shape of a 2-second stimulus response function, consider something akin to what is also in the help:

3dDeconvolve -nodata 50 1 -polort -1 -num_stimts 1 -stim_times 1 '1D: 0' 'MION(2)' -x1D stdout: | 1dplot -stdin -one -thick

Does this seem reasonable?

  • rick