function output_trains=random_train(pulse_duration_presyn,pulse_duration_postsyn,samples_per_ms,halfsecond,trial,hy,cs,samples_per_trigger,...
    OVSF_presyn,OVSF_postsyn,output_channel_to_presynaptic,evoke_postsynpatic_AP_this_trial,end_postsyn_current,postsyn_AP_delay)

%this function gets information about how many IPIs, what range (if any) IPIs can vary over, and how many steps are permitted within the range (this info comes in the form of a matrix, hy)
%it then randomly generates a first train, in accord with the specifications, and creates a tally matrix
%recording which values were assigned to each interval each dimension of the tally matrix corresponds to one IPI, for example rows corresponds to IPIa, cols to IPIb
%using this tally matrix ensures that possible trains are played once before any is played twice, and similarly for subsequent repetitions
samples_per_pulse_presyn=pulse_duration_presyn*samples_per_ms
samples_per_pulse_postsyn=pulse_duration_postsyn*samples_per_ms;
postsyn_AP_delay=postsyn_AP_delay*samples_per_ms;
%-----------------
if hy
    global tally
    au=hy(1,:);                                 %the first row of hy is the number of possible values for each IPI
    %cannot_occur=[3 5 6 7 8 10 11 12 13 14 15 16 17 18]   %THIS LINE is part of the effort to reduce the possible values of IPIa
    if trial==1
        %na=cannot_occur(1)                     %THIS LINE is part of the effort to reduce the possible values of IPIa
        %while find (na(1)== cannot_occur)      %THIS LOOP is part of the effort to reduce the possible values of IPIa 
            na=rand(1,length(au));
            na=na.*au;
            na=ceil(na);                        %then na goes and provides the info needed to create the output train
            %end
        tally=zeros(au);
        if length(au)<2                         %the eventuality where au is only one element long, that is, there is only one IPI, that is, there are only two presynaptic APs
            tally=zeros(au,1);
        end
        dummest=length(au);
        nummest=prod(au);
        while dummest                           %this loop exists so that this emmfile can handle hy of any size (that is, any number of IPIs)
            nummest=nummest-(((au(dummest)-na(dummest))/au(dummest))*prod(au(1:dummest)));
            dummest=dummest-1;    
        end
        tally(nummest)=tally(nummest)+1
        %tally(cannot_occur)=1                  %THIS LINE is part of the effort to reduce the possible values of IPIa
    end

    if trial>1
        %tally
        ca_before=min(tally);
        for iii=1:length(size(tally))-1         %this tomfoolery is necessary bc 'min' takes the min along each dimension, so need 'number of [non-singleton] dimensions of tally' times
            ca_before=min(ca_before);           %the first time is outside the for loop (if one or more of tally's dimensions are singleton, this won't change the loop's behavior)  
        end
        ca_after=ca_before-1;
        while ca_before~=ca_after
            na=rand(1,length(au));
            na=na.*au;
            na=ceil(na); 
            dummest=length(au);
            nummest=prod(au);
            while dummest                       %this loop exists so that this emmfile can handle hy of any size (that is, any number of IPIs)
                nummest=nummest-(((au(dummest)-na(dummest))/au(dummest))*prod(au(1:dummest)));
                dummest=dummest-1;    
            end
            ca_after=tally(nummest);            %escape the while loop if the randomly generated value's spot in the tally matrix has the same value as the min of the tally matrix
        end
        tally(nummest)=tally(nummest)+1
        %if min(tally(:,1))==max(tally(:,1))    %THIS LOOP was added for when each possible IPI has happened exactly as many times as each other possible IPI -- part of the "THIS LINE" modification oct 29 2003
            %tally(cannot_occur)=tally(cannot_occur)+1   %THIS LINE is part of the effort to reduce the possible values of IPIa
        %end
    end
    %then, after the while loop, na goes and provides the info needed to create the output train
    %--------------------
    ba=na-1;                                    %correcting, for indexing (see next few lines)
    intervuls=ba.*hy(3,:);
    intervuls=intervuls+hy(2,:);
    intervuls=intervuls*samples_per_ms;         %translating the intervals from milliseconds into samples

    train_pre=zeros(samples_per_trigger,1);
    %ones=size(train_pre)
    train_pre(3001:3000+(100*samples_per_ms))=-1/(4*OVSF_presyn);   %assuming Multiclamp Commander is set at 20mv/V, after multiplication by OVSF_presyn below, %feb 17 2004 switched from 10ms to 50ms duration
    %twos=size(train_pre)                                          %this will give a hyperpolarizing pulse of -5mv for 10ms starting at ms300
    train_pre(halfsecond+1:halfsecond+samples_per_pulse_presyn)=1; %the first pulse, which occurs beginning at halfsecond and lasts (samples_per_ms*pulse_duration) samples
    for jjj=1:length(ba)                     %the length of ba = the number of IPIs -- with the initial pulse @ halfsecond, the # of IPIs = the # of remaining pulses
        fe=halfsecond+sum(intervuls(1:jjj)); %now interval is beginning of one pulse to beginning of the next (old way was end of one to beginning of the next -- 
                                             %halfsecond+samples_per_pulse+sum(intervuls(1:jjj))+((jjj-1)*samples_per_pulse)
        train_pre(fe+1:fe+samples_per_pulse_presyn)=1;
    end 
elseif isempty(hy)
    train_pre=zeros(samples_per_trigger,1);
    %ones=size(train_pre)
    train_pre(3001:3000+(100*samples_per_ms))=-1/(4*OVSF_presyn);   %assuming Multiclamp Commander is set at 20mv/V, after multiplication by OVSF_presyn below, %feb 17 2004 switched from 10ms to 50ms duration
    %twos=size(train_pre)                                          %this will give a hyperpolarizing pulse of -5mv for 10ms starting at ms300
    train_pre(halfsecond+1:halfsecond+samples_per_pulse_presyn)=1;
end                                                           
train_pre=OVSF_presyn*train_pre;
%champ=find(train_pre)

%making the pulse train for the postsynaptic neuron
%the pulse train will be in the output train from the assigned time + one sample to the assigned time + a pulse's worth of samples
%example: if the pulse is set for 600ms, sampling 10kHz, and pulse_duration 1ms, the pulse will last from samples 6001-6010, inclusive
%this keeps it consistent with the presynaptic pulses
train_post=zeros(samples_per_trigger,1);
train_post(3001:3000+(100*samples_per_ms))=-1/(4*OVSF_postsyn);
if evoke_postsynpatic_AP_this_trial
    postsynaptic_evoke_time=end_postsyn_current+postsyn_AP_delay
    train_post(postsynaptic_evoke_time+1:postsynaptic_evoke_time+samples_per_pulse_postsyn)=1;
    %train_post(halfsecond+postsyn_AP_delay+1:halfsecond+postsyn_AP_delay+samples_per_pulse_postsyn)=1;
end

if  cs
    %this has not been created b/c a choice must be made as to whether presyn and postsyn stim times should vary independently or in concert
    %if both are present and both are random it would be more efficient to have them vary in concert
    %(i.e., s.t. no combinatorial possibility of presyn and postsyn times can occur more than one time more than any other possibility)
end
train_post=OVSF_postsyn*train_post;

%threes=size(train_pre)
%fours=size(train_post)
output_trains=[train_pre train_post];

if output_channel_to_presynaptic==2  %switching things around when the presynaptic neuron is patched through the second output channel
        output_trains=fliplr(output_trains);
end

%train_spritz is the train determining when the picospritzer is picospritzing
%train_cam is the train determining when the camera shutter is gated