Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


PreProc.m

Go to the documentation of this file.
00001 function [err, Qd, s, termname, nterms, sindices, dfbothSS, modw, modwo, tnames, dfterm, dfe, Contr] = PreProc(n, NF, group, varnames, FL, Contr, cov, unbalanced)
00002 %
00003 %   [err, Qd, Rd, sindices, dfboth, modw, modwo, dfx] = PreProc(n,group,varnames)
00004 %
00005 %Purpose:
00006 %   
00007 %  Returns QR decomposition results for the design matrix projected to null space 
00008 %   
00009 %Input Parameters:
00010 %   n: number of datasets = total # of combinations including repeats
00011 %   group: cell array of factor levels
00012 %   varnames: 
00013 %   
00014 %Output Parameters:
00015 %   err : 0 No Problem
00016 %       : 1  Problems
00017 %   
00018 %   
00019 %      
00020 %Key Terms:
00021 %   
00022 %More Info :
00023 %   
00024 %   
00025 %   
00026 %
00027 %     Author : Gang Chen
00028 %     Date : Tue Mar 23 13:57:52 EST 2004
00029 %     SSCC/NIMH/ NIH, Bethesda MD 20892
00030 
00031 
00032 %Define the function name for easy referencing
00033 FuncName = 'PreProc.m';
00034 
00035 %Debug Flag
00036 DBG = 1;
00037 
00038 %initailize return variables
00039 err = 1;
00040 
00041 % Don't worry about NaN's at this point.
00042 group = group(:);    % what's it for?
00043 ng = length(group);  % number of factors
00044 termlist = makemodel(ng, ng);  % Generate terms for all main effects plus various interactions
00045 
00046 for j=1:ng
00047    gj = group{j};
00048    if (size(gj,1) == 1), gj = gj(:); end
00049    if (size(gj,1) ~= n)
00050       error('Factor %d must have %d elements.',j,n);
00051    end
00052    if (ischar(gj)), gj = cellstr(gj); end
00053    group{j} = gj;
00054 end
00055 
00056 gdum = cell(ng,1);
00057 dfvar = zeros(ng,1);
00058 
00059 if (unbalanced.yes == 0), % Balanced designs
00060    vconstr = cell(ng,1);
00061    %vmean = cell(ng,1);  %vmean is never used!!!
00062 end
00063 
00064 for j=1:ng   % for each factor
00065    gj = group{j};
00066    [gij,gnj] = grp2idx(gj);   % Create index vector from a grouping variable: gij is a vector 
00067                                    % taking integer values from 1 up to the number of unique entries in gj
00068                                                                                 % gnj is a cell array of names, so that gnj(gij) reproduces gj
00069    nlevels = size(gnj,1);     % levels for this factor
00070    dfvar(j) = nlevels - 1;    % D. F. for this factor
00071 
00072    if (unbalanced.yes == 0),    % balanced
00073       if (cov.do & j==cov.marker)        
00074               gdum{j} = gj;
00075          dfvar(j) = 1;           % D. F. = 1
00076          vconstr{j} = zeros(0,1);
00077 %        vmean{j} = 1;          
00078       else
00079          gdum{j} = idummy(gij, 3);
00080          vconstr{j} = idummy(1:nlevels)';
00081 %        vmean{j} = ones(1,nlevels) / nlevels;  % array (1Xnlevels) of one ones, but vmean is never used in the code!!!!!!!!!1
00082            end
00083         else % Unbalanced designs       
00084            if (cov.do & j==cov.marker)        
00085               gdum{j} = gj;
00086          dfvar(j) = 1;           % D. F. = 1
00087          vconstr{j} = zeros(0,1);
00088 %        vmean{j} = 1;          
00089       else
00090                    gdum{j} = idummy(gij, 3);
00091                 end       
00092         end % if (unbalanced.yes == 0): Only for balanced designs
00093                 
00094 end
00095 
00096 % Create dummy variable arrays for each term in the model.
00097 nterms = size(termlist,1);             % Number of rows (1st dimension) in termlist
00098 [sterms,sindex] = sortrows(termlist);  % Sort terms in ascending order. 
00099 ncols = 1;
00100 nconstr = 0;
00101 
00102 termdum = cell(nterms, 1);        % cell array of dummy variables which are design matrix cols
00103 termconstr = cell(nterms,1);      % constraints to make each term well defined
00104 levelcodes = cell(nterms, 1);     % codes for levels of each M row
00105 tnames = cell(nterms, 1);         % name for entire term, e.g. A*B
00106 dfterm0 = zeros(nterms, 1);       % nominal d.f. for each term
00107 termvars = cell(nterms, 1);       % list of vars in each term
00108 termlength = zeros(size(sindex)); % length of each term (number of columns)
00109 
00110 %randomterm = find(termlist*randomvar > 0);  % indices of random terms
00111 
00112 % For each term,
00113 for j=1:nterms
00114    % Loop over elements of the term
00115    df0 = 1;
00116    tm = sterms(j,:);
00117    tdum = [];         % empty term so far
00118    tconstr = 1;       % empty constraints so far
00119    tn = '';           % blank name so far
00120    vars = find(tm);   % Find indices of nonzero elements
00121    for varidx = 1:length(vars)
00122       % Process each variable participating in this term
00123       varnum = vars(varidx);          % variable name
00124       tm(varnum) = 0;                 % term without this variable
00125       df0 = df0 * dfvar(varnum);      % d.f. so far
00126 
00127       % Combine its dummy variable with the part computed so far
00128       G = gdum{varnum};           % dummy vars for this grouping var
00129       nlevterm = size(tdum,2);    % levels for term so far
00130       nlevgrp  = size(G,2);       % levels for this grouping var
00131       tdum = termcross(G,tdum);   % combine G into term dummy vars
00132 
00133       % Construct the term name and constraints matrix
00134 %      if (ismember(varnum, NF) & cov.do),    % for the covariate, which is the last factor
00135                 if (ismember(varnum, cov.marker) & cov.do),    % for the covariate, which is the last factor
00136          vconstr = ones(0,1);
00137       else
00138          vconstr = ones(1, nlevgrp);
00139       end
00140       if (isempty(tn))
00141          tn = varnames{varnum};
00142          tconstr = vconstr;
00143       else
00144          tn = [varnames{varnum} '*' tn];
00145          tconstr = [kron(vconstr,eye(size(tconstr,2)));
00146                     kron(eye(length(vconstr)),tconstr)];   % Kronecker 
00147       end
00148 
00149       % If the rest of this term is computed, take advantage of that
00150       prevterms = sterms(1:j-1,:);
00151       oldtm = find((prevterms * tm') == sum(tm));      % same vars in old term
00152       oldtm = oldtm((prevterms(oldtm,:) * ~tm') == 0); % and no others
00153       if (length(oldtm) > 0)
00154          k = sindex(oldtm(1));
00155          tdum = termcross(termdum{k}, tdum);
00156          oconstr = termconstr{k};
00157          tconstr = [kron(tconstr,              eye(size(oconstr,2)));
00158                     kron(eye(size(tconstr,2)), oconstr)];
00159          tn = [tn '*' tnames{k}];
00160          df0 = df0 * dfterm0(k);
00161          break;
00162       end
00163    end
00164 
00165    % Store this term's dummy variables and name
00166    k = size(tdum, 2);
00167    termlength(sindex(j),1) = k;
00168    ncols = ncols + k;
00169    sj = sindex(j);
00170    termdum{sj} = tdum;
00171    termconstr{sj} = tconstr;
00172    termvars{sj} = vars;
00173    levelcodes{sj} = fullfact(dfvar(vars)+1);
00174    if (isempty(tn)), tn = 'Constant'; end
00175    tnames{sj,1} = tn;
00176    dfterm0(sj) = df0;
00177    nconstr = nconstr + size(tconstr,1);
00178 end
00179 tnames{length(tnames)+1,1} = 'Error';
00180 
00181 % Create the full design matrix
00182 dmat = ones(n, ncols);        % to hold design matrix of nXncols
00183 cmat = zeros(nconstr,ncols);  % to hold constraints matrix
00184 cbase = 0;                    % base from which to fill in cmat
00185 termname = zeros(ncols,1);
00186 termstart = cumsum([2; termlength(1:end-1)]);
00187 termend = termstart + termlength - 1;
00188 for j=1:nterms
00189    clist = termstart(j):termend(j);
00190    dmat(:, clist) = termdum{j};
00191    C = termconstr{j};
00192    nC = size(C,1);
00193    cmat(cbase+1:cbase+nC,clist) = C;
00194    termname(clist) = j;
00195    cbase = cbase + nC;
00196 end
00197 
00198 [err, Qd, dfx, dmat2] = QRDecom(dmat, cmat);
00199 %dfe = n - dfx;
00200 
00201 % Determine which models to compare for testing each term
00202 ssw  = -ones(nterms, 1);      % sum of squares with this term
00203 sswo = ssw;                   % sum of squares without this term
00204 dfw  = ssw;                   % residual d.f. with this term
00205 dfwo = ssw;                   % residual d.f. without this term
00206 
00207 if (unbalanced.yes == 1)
00208    modw = tril(ones(nterms)); % get model with this term
00209    k = nterms;                % locations of model with all terms
00210 else
00211 
00212 % Only apply type III for sums of squares
00213 modw = ones(nterms);
00214 %k = 1:nterms;
00215 %TnotC = termsnotcontained(termlist);
00216 
00217 end % if (unbalanced.yes == 1)
00218 
00219 modw = logical(modw);                  % get model with this term
00220 modwo = logical(modw - eye(nterms));   % get model without this term
00221 
00222 dfw(1:nterms) = dfx;
00223 
00224 % Fit each model separately
00225 dfboth = [dfw; dfwo];
00226 dfbothSS = dfboth;  % For usage in ss.m
00227 
00228 % Consider interactions before their components for type 3 ss, so
00229 % examine the terms in decreasing order of the number factors in the term
00230 
00231 
00232 if (unbalanced.yes == 1)
00233    sindices = [(1:size(termlist,1)), (1:size(termlist,1))]';    
00234 else    
00235 termsize = sum(termlist,2)';      %sum of all the elements along 2nd dimension (row)
00236 [stermsize,sindices] = sort(termsize); % sort in ascending order, output is stored in stermsize; sindices is the index for the new array
00237 sindices = [sindices(:); sindices(:)];
00238 
00239 end % if (unbalanced.yes == 1)
00240 
00241 % Here QR decomposition is done, which is voxel independent
00242 
00243 s(length(sindices)).Qdt = [];
00244 
00245 for j=length(sindices):-1:1
00246    % Find the next model index to fit
00247    k = sindices(j);
00248    
00249    % Look in unsorted arrays to see if we have already fit this model
00250    if j>nterms
00251       k0 = k+nterms;
00252    else
00253       k0 = k;
00254    end
00255    if dfboth(k0)~=-1
00256       continue
00257    end
00258    
00259    % Find the model with this index
00260    if (j > nterms)
00261       thismod = modwo(k, :);
00262    else
00263       thismod = modw(k, :);
00264    end
00265    
00266    % Get the design matrix for this model
00267    keepterms = find(thismod);
00268    clist = ismember(termname, [0 keepterms]);
00269    X = dmat2(:,clist);
00270    C = cmat(:,clist);
00271 
00272    % Fit this term 
00273         [err, s(j).Qdt, dfx0] = QRDecom(X, C);  
00274 
00275    % Use these results for each term that requires them
00276 
00277    mod0 = repmat(thismod, nterms, 1);
00278    k = find(all(modw == mod0, 2));    
00279    dfw(k) = dfx0;
00280    dfboth(k) = 0;
00281         
00282    k = find(all(modwo == mod0, 2));
00283    dfwo(k) = dfx0;
00284    dfboth(nterms+k) = 0;
00285 end
00286 clear mod0
00287 
00288 dfterm = dfw - dfwo;
00289 dfe = n-dfx;   %residual degrees of freedom
00290 
00291 if (Contr.do == 1),
00292 
00293    % In design matrix dmat, the first column is all one's, for the total mean. Then there are totally
00294    % FL(1).N_level + FL(2).N_level + FL(3).N_level + FL(4).N_level columns for the main effects. 
00295    % Next 2nd order interactions, 3rd order interaction, and 4th order interactions.
00296 
00297    % Store only those mean columns in design matrix. 
00298 
00299    %num_col0 = 1;  % the 1st column is for grand mean (0 order)
00300 
00301    num_col(1) = 0;
00302    for (i = 1:1:NF),
00303       num_col(1) = num_col(1) + FL(i).N_level;   %
00304    end
00305 
00306    %  Ignore 1st col since it is total mean
00307    %dmat_mean = dmat(:, (num_col0 + 1):(num_col0 + num_col(1)));
00308 
00309    % Get the number in the sum for each mean, which happens to be in the diagonal of X'X.
00310    % This can also be otained through the user input variables, but it is generic with
00311    % the matrix operation, especially for unbalanced design.
00312    %sum_num = diag(dmat_mean' * dmat_mean);
00313 
00314 
00315    if (NF > 1),
00316       num_col(2) = 0;
00317       for (i = 1:1:(NF-1)),
00318       for (j = (i+1):1:NF),
00319          num_col(2) = num_col(2) + FL(i).N_level*FL(j).N_level;    %Columns for 2nd order interactions
00320       end
00321       end
00322    end
00323 
00324    if (NF > 2),
00325       num_col(3) = 0;
00326       for (i = 1:1:(NF-2)),
00327       for (j = (i+1):1:(NF-1)),
00328         for (k = (j+1):1:NF),
00329          num_col(3) = num_col(3) + FL(i).N_level*FL(j).N_level*FL(k).N_level;    %Columns for 3rd order interactions
00330       end
00331       end
00332         end
00333    end
00334 
00335    %if (NF == 4),
00336    %   num_col(4) = 1;
00337    %    for (i = 1:1:NF),
00338    %       num_col(4) = num_col(4)*FL(i).N_level;  %Columns for 4th order interactions
00339    %    end     
00340    %end
00341 
00342    % for every design
00343    if (Contr.ord1.tot > 0),             % 1st order contrasts   
00344       [err, Contr] = ContrVec(1, n, NF, group, dmat, Contr, FL, num_col);
00345    end   % if (Contr1.tot > 0)
00346 
00347    if (NF > 1 & Contr.ord2.tot > 0),  % 2nd order contrasts   
00348       [err, Contr] = ContrVec(2, n, NF, group, dmat, Contr, FL, num_col);
00349    end   % if (Contr2.tot > 0)
00350 
00351    if (NF > 2 & Contr.ord3.tot > 0),  % 3rd order contrasts   
00352       [err, Contr] = ContrVec(3, n, NF, group, dmat, Contr, FL, num_col);
00353    end   % if (Contr3.tot > 0)
00354         
00355         if (NF > 3 & Contr.ord4.tot > 0),  % 4th order contrasts   
00356       [err, Contr] = ContrVec(4, n, NF, group, dmat, Contr, FL, num_col);
00357    end   % if (Contr3.tot > 0)
00358 
00359 end % if (Contr.do == 1)
00360 
00361 err = 0;
00362 return;
 

Powered by Plone

This site conforms to the following standards: