function  CMETAA  = readCMETAA(fid)
%
% <<<<<<<<<< CLASSIFICATION: UNCLASSIFIED >>>>>>>>>>
%
% READCMETAA Create structure for metadata fields.
%   CMETAA = READCMETAA(FID) returns a structure of fields and their
%   associated values.

% Written by Matt Donath, NGA, matthew.b.donath@nga.ic.gov
% References:
%  > MIL-STD-2500A, NATIONAL IMAGERY TRANSMISSION FORMAT VERSION 2.0
%  > MIL-STD-2500C, NATIONAL IMAGERY TRANSMISSION FORMAT VERSION 2.1
%  > STDI-0001,     NATIONAL SUPPORT DATA EXTENSIONS (SDE)(VERSION 1.3/CN2)
%                   FOR THE NATIONAL IMAGERY TRANSMISSION FORMAT (NITF)
%  > STDI-0002,     THE COMPENDIUM OF CONTROLLED EXTENSIONS (CE) FOR THE
%                   NATIONAL IMAGERY TRANSMISSION FORMAT (NITF) VERSION 2.1
%
% //////////////////////////////////////////
% /// CLASSIFICATION: UNCLASSIFIED       ///
% //////////////////////////////////////////

%% Create the metadata structure for CMETAA.

CMETAA.CETAG = fread(fid,6,'uint8=>char')';
CMETAA.CEL = str2double(fread(fid,5,'uint8=>char')');

CMETAA.RELATED_TRES = strtrim(fread(fid,2,'uint8=>char')');
CMETAA.RELATED_TRES = strtrim(fread(fid,120,'uint8=>char')');
CMETAA.RD_PRC_NO = strtrim(fread(fid,12,'uint8=>char')');
CMETAA.IF_PROCESS = strtrim(fread(fid,4,'uint8=>char')');
CMETAA.RD_CEN_FREQ = strtrim(fread(fid,4,'uint8=>char')');
CMETAA.RD_MODE = strtrim(fread(fid,5,'uint8=>char')');
CMETAA.RD_PATCH_NO = str2double(fread(fid,4,'uint8=>char')');

CMETAA.CMPLX_DOMAIN = strtrim(fread(fid,5,'uint8=>char')');
CMETAA.CMPLX_MAG_REMAP_TYPE = strtrim(fread(fid,4,'uint8=>char')');
CMETAA.CMPLX_LIN_SCALE = str2double(fread(fid,7,'uint8=>char')');
CMETAA.CMPLX_AVG_POWER = str2double(fread(fid,7,'uint8=>char')');
CMETAA.CMPLX_LINLOG_TP = str2double(fread(fid,5,'uint8=>char')');
CMETAA.CMPLX_PHASE_QUANT_FLAG = strtrim(fread(fid,3,'uint8=>char')');
CMETAA.CMPLX_PHASE_QUANT_BIT_DEPTH = str2double(fread(fid,2,'uint8=>char')');
CMETAA.CMPLX_SIZE_1 = str2double(fread(fid,2,'uint8=>char')');
CMETAA.CMPLX_IC_1 = strtrim(fread(fid,2,'uint8=>char')');
CMETAA.CMPLX_SIZE_2 = str2double(fread(fid,2,'uint8=>char')');
CMETAA.CMPLX_IC_2 = strtrim(fread(fid,2,'uint8=>char')');
CMETAA.CMPLX_IC_BPP = str2double(fread(fid,5,'uint8=>char')');
CMETAA.CMPLX_WEIGHT = strtrim(fread(fid,3,'uint8=>char')');
CMETAA.CMPLX_AZ_SLL = str2double(fread(fid,2,'uint8=>char')');
CMETAA.CMPLX_RNG_SLL = str2double(fread(fid,2,'uint8=>char')');
CMETAA.CMPLX_AZ_TAY_NBAR = str2double(fread(fid,2,'uint8=>char')');
CMETAA.CMPLX_RNG_TAY_NBAR = str2double(fread(fid,2,'uint8=>char')');
CMETAA.CMPLX_WEIGHT_NORM = strtrim(fread(fid,3,'uint8=>char')');
CMETAA.CMPLX_SIGNAL_PLANE = strtrim(fread(fid,1,'uint8=>char')');

CMETAA.IF_DC_SF_ROW = str2double(fread(fid,6,'uint8=>char')');
CMETAA.IF_DC_SF_COL = str2double(fread(fid,6,'uint8=>char')');

for lp = 1:4
    CMETAA.IF_PATCH_ROW(lp) = str2double(fread(fid,6,'uint8=>char')');
    CMETAA.IF_PATCH_COL(lp) = str2double(fread(fid,6,'uint8=>char')');
end

CMETAA.IF_DC_IS_ROW = str2double(fread(fid,8,'uint8=>char')');
CMETAA.IF_DC_IS_COL = str2double(fread(fid,8,'uint8=>char')');
CMETAA.IF_IMG_ROW_DC = str2double(fread(fid,8,'uint8=>char')');
CMETAA.IF_IMG_COL_DC = str2double(fread(fid,8,'uint8=>char')');

for lp = 1:4
    CMETAA.IF_TILE_ROW(lp) = str2double(fread(fid,6,'uint8=>char')');
    CMETAA.IF_TILE_COL(lp) = str2double(fread(fid,6,'uint8=>char')');
end

CMETAA.IF_RD = strtrim(fread(fid,1,'uint8=>char')');
CMETAA.IF_RGWLK = strtrim(fread(fid,1,'uint8=>char')');
CMETAA.IF_KEYSTN = strtrim(fread(fid,1,'uint8=>char')');
CMETAA.IF_LINSFT = strtrim(fread(fid,1,'uint8=>char')');
CMETAA.IF_SUBPATCH = strtrim(fread(fid,1,'uint8=>char')');
CMETAA.IF_GEODIST = strtrim(fread(fid,1,'uint8=>char')');
CMETAA.IF_RGFO = strtrim(fread(fid,1,'uint8=>char')');
CMETAA.IF_BEAM_COMP = strtrim(fread(fid,1,'uint8=>char')');
CMETAA.IF_RGRES = str2double(fread(fid,8,'uint8=>char')');
CMETAA.IF_AZRES = str2double(fread(fid,8,'uint8=>char')');
CMETAA.IF_RSS = str2double(fread(fid,8,'uint8=>char')');
CMETAA.IF_AZSS = str2double(fread(fid,8,'uint8=>char')');
CMETAA.IF_RSR = str2double(fread(fid,8,'uint8=>char')');
CMETAA.IF_AZSR = str2double(fread(fid,8,'uint8=>char')');
CMETAA.IF_RFFT_SAMP = str2double(fread(fid,7,'uint8=>char')');
CMETAA.IF_AZFFT_SAMP = str2double(fread(fid,7,'uint8=>char')');
CMETAA.IF_RFFT_TOT = str2double(fread(fid,7,'uint8=>char')');
CMETAA.IF_AZFFT_TOT = str2double(fread(fid,7,'uint8=>char')');
CMETAA.IF_SUBP_ROW = str2double(fread(fid,6,'uint8=>char')');
CMETAA.IF_SUBP_COL = str2double(fread(fid,6,'uint8=>char')');
CMETAA.IF_SUB_RG = str2double(fread(fid,4,'uint8=>char')');
CMETAA.IF_SUB_AZ = str2double(fread(fid,4,'uint8=>char')');
CMETAA.IF_RFFTS = strtrim(fread(fid,1,'uint8=>char')');
CMETAA.IF_AFFTS = strtrim(fread(fid,1,'uint8=>char')');
CMETAA.IF_RANGE_DATA = strtrim(fread(fid,7,'uint8=>char')');
CMETAA.IF_INCPH = strtrim(fread(fid,1,'uint8=>char')');
CMETAA.IF_SR_NAME1 = strtrim(fread(fid,8,'uint8=>char')');
CMETAA.IF_SR_AMOUNT1 = str2double(fread(fid,8,'uint8=>char')');
CMETAA.IF_SR_NAME2 = strtrim(fread(fid,8,'uint8=>char')');
CMETAA.IF_SR_AMOUNT2 = str2double(fread(fid,8,'uint8=>char')');
CMETAA.IF_SR_NAME3 = strtrim(fread(fid,8,'uint8=>char')');
CMETAA.IF_SR_AMOUNT3 = str2double(fread(fid,8,'uint8=>char')');

for lp = 1:3
    CMETAA.AF_TYPE{lp} = strtrim(fread(fid,5,'uint8=>char')');
end

CMETAA.POL_TR = strtrim(fread(fid,1,'uint8=>char')');
CMETAA.POL_RE = strtrim(fread(fid,1,'uint8=>char')');
CMETAA.POL_REFERENCE = strtrim(fread(fid,40,'uint8=>char')');
CMETAA.POL = strtrim(fread(fid,1,'uint8=>char')');
CMETAA.POL_REG = strtrim(fread(fid,1,'uint8=>char')');
CMETAA.POL_ISO_1 = str2double(fread(fid,5,'uint8=>char')');
CMETAA.POL_BAL = strtrim(fread(fid,1,'uint8=>char')');
CMETAA.POL_BAL_MAG = str2double(fread(fid,8,'uint8=>char')');
CMETAA.POL_BAL_PHS = str2double(fread(fid,8,'uint8=>char')');
CMETAA.POL_HCOMP = strtrim(fread(fid,1,'uint8=>char')');
CMETAA.POL_HCOMP_BASIS = strtrim(fread(fid,10,'uint8=>char')');

for lp = 1:3
    CMETAA.POL_HCOMP_COEF(lp) = str2double(fread(fid,9,'uint8=>char')');
end

CMETAA.POL_AFCOMP = strtrim(fread(fid,1,'uint8=>char')');
CMETAA.POL_SPARE_A = strtrim(fread(fid,15,'uint8=>char')');
CMETAA.POL_SPARE_N = strtrim(fread(fid,9,'uint8=>char')');

CMETAA.T_UTC_YYYYMMMDD = strtrim(fread(fid,9,'uint8=>char')');
CMETAA.T_HHMMSSUTC = strtrim(fread(fid,6,'uint8=>char')');
CMETAA.T_HHMMSSLOCAL = strtrim(fread(fid,6,'uint8=>char')');

CMETAA.CG_SRAC = str2double(fread(fid,11,'uint8=>char')');
CMETAA.CG_SLANT_CONFIDENCE = str2double(fread(fid,7,'uint8=>char')');
CMETAA.CG_CROSS = str2double(fread(fid,11,'uint8=>char')');
CMETAA.CG_CROSS_CONFIDENCE = str2double(fread(fid,7,'uint8=>char')');
CMETAA.CG_CAAC = str2double(fread(fid,9,'uint8=>char')');
CMETAA.CG_CONE_CONFIDENCE = str2double(fread(fid,6,'uint8=>char')');
CMETAA.CG_GPSAC = str2double(fread(fid,8,'uint8=>char')');
CMETAA.CG_GPSAC_CONFIDENCE = str2double(fread(fid,6,'uint8=>char')');
CMETAA.CG_SQUINT = str2double(fread(fid,8,'uint8=>char')');
CMETAA.CG_GAAC = str2double(fread(fid,7,'uint8=>char')');
CMETAA.CG_GAAC_CONFIDENCE = str2double(fread(fid,6,'uint8=>char')');
CMETAA.CG_INCIDENT = str2double(fread(fid,7,'uint8=>char')');
CMETAA.CG_SLOPE = str2double(fread(fid,7,'uint8=>char')');
CMETAA.CG_TILT = str2double(fread(fid,8,'uint8=>char')');
CMETAA.CG_LD = fread(fid,1,'uint8=>char')';
CMETAA.CG_NORTH = str2double(fread(fid,8,'uint8=>char')');
CMETAA.CG_NORTH_CONFIDENCE = str2double(fread(fid,6,'uint8=>char')');
CMETAA.CG_EAST = str2double(fread(fid,8,'uint8=>char')');
CMETAA.CG_RLOS = str2double(fread(fid,8,'uint8=>char')');
CMETAA.CG_LOS_CONFIDENCE = str2double(fread(fid,6,'uint8=>char')');
CMETAA.CG_LAYOVER = str2double(fread(fid,8,'uint8=>char')');
CMETAA.CG_SHADOW = str2double(fread(fid,8,'uint8=>char')');
CMETAA.CG_OPM = str2double(fread(fid,7,'uint8=>char')');
CMETAA.CG_MODEL = strtrim(fread(fid,5,'uint8=>char')');

CMETAA.CG_AMPT_X = str2double(fread(fid,13,'uint8=>char')');
CMETAA.CG_AMPT_Y = str2double(fread(fid,13,'uint8=>char')');
CMETAA.CG_AMPT_Z = str2double(fread(fid,13,'uint8=>char')');
CMETAA.CG_AP_CONF_XY = str2double(fread(fid,6,'uint8=>char')');
CMETAA.CG_AP_CONF_Z = str2double(fread(fid,6,'uint8=>char')');
CMETAA.CG_APCEN_X = str2double(fread(fid,13,'uint8=>char')');
CMETAA.CG_APCEN_Y = str2double(fread(fid,13,'uint8=>char')');
CMETAA.CG_APCEN_Z = str2double(fread(fid,13,'uint8=>char')');
CMETAA.CG_APER_CONF_XY = str2double(fread(fid,6,'uint8=>char')');
CMETAA.CG_APER_CONF_Z = str2double(fread(fid,6,'uint8=>char')');
CMETAA.CG_FPNUV_X = str2double(fread(fid,9,'uint8=>char')');
CMETAA.CG_FPNUV_Y = str2double(fread(fid,9,'uint8=>char')');
CMETAA.CG_FPNUV_Z = str2double(fread(fid,9,'uint8=>char')');
CMETAA.CG_IDPNUVX = str2double(fread(fid,9,'uint8=>char')');
CMETAA.CG_IDPNUVY = str2double(fread(fid,9,'uint8=>char')');
CMETAA.CG_IDPNUVZ = str2double(fread(fid,9,'uint8=>char')');
CMETAA.CG_SCECN_X = str2double(fread(fid,13,'uint8=>char')');
CMETAA.CG_SCECN_Y = str2double(fread(fid,13,'uint8=>char')');
CMETAA.CG_SCECN_Z = str2double(fread(fid,13,'uint8=>char')');
CMETAA.CG_SC_CONF_XY = str2double(fread(fid,6,'uint8=>char')');
CMETAA.CG_SC_CONF_Z = str2double(fread(fid,6,'uint8=>char')');
CMETAA.CG_SWWD = str2double(fread(fid,8,'uint8=>char')');
CMETAA.CG_SNVEL_X = str2double(fread(fid,10,'uint8=>char')');
CMETAA.CG_SNVEL_Y = str2double(fread(fid,10,'uint8=>char')');
CMETAA.CG_SNVEL_Z = str2double(fread(fid,10,'uint8=>char')');
CMETAA.CG_SNACC_X = str2double(fread(fid,10,'uint8=>char')');
CMETAA.CG_SNACC_Y = str2double(fread(fid,10,'uint8=>char')');
CMETAA.CG_SNACC_Z = str2double(fread(fid,10,'uint8=>char')');
CMETAA.CG_SNATT_ROLL = str2double(fread(fid,8,'uint8=>char')');
CMETAA.CG_SNATT_PITCH = str2double(fread(fid,8,'uint8=>char')');
CMETAA.CG_SNATT_YAW = str2double(fread(fid,8,'uint8=>char')');
CMETAA.CG_GTP_X = str2double(fread(fid,9,'uint8=>char')');
CMETAA.CG_GTP_Y = str2double(fread(fid,9,'uint8=>char')');
CMETAA.CG_GTP_Z = str2double(fread(fid,9,'uint8=>char')');

CMETAA.CG_MAP_TYPE = strtrim(fread(fid,4,'uint8=>char')');

if strcmp(CMETAA.CG_MAP_TYPE,'GEOD')
    CMETAA.CG_PATCH_LATCEN = str2double(fread(fid,11,'uint8=>char')');
    CMETAA.CG_PATCH_LNGCEN = str2double(fread(fid,12,'uint8=>char')');
    CMETAA.CG_PATCH_LTCORUL = str2double(fread(fid,11,'uint8=>char')');
    CMETAA.CG_PATCH_LGCORUL = str2double(fread(fid,12,'uint8=>char')');
    CMETAA.CG_PATCH_LTCORUR = str2double(fread(fid,11,'uint8=>char')');
    CMETAA.CG_PATCH_LGCORUR = str2double(fread(fid,12,'uint8=>char')');
    CMETAA.CG_PATCH_LTCORLR = str2double(fread(fid,11,'uint8=>char')');
    CMETAA.CG_PATCH_LGCORLR = str2double(fread(fid,12,'uint8=>char')');
    CMETAA.CG_PATCH_LTCORLL = str2double(fread(fid,11,'uint8=>char')');
    CMETAA.CG_PATCH_LNGCOLL = str2double(fread(fid,12,'uint8=>char')');
    CMETAA.CG_PATCH_LAT_CONFIDENCE = str2double(fread(fid,9,'uint8=>char')');
    CMETAA.CG_PATCH_LONG_CONFIDENCE = str2double(fread(fid,9,'uint8=>char')');
elseif strcmp(CMETAA.CG_MAP_TYPE,'MGRS')
    CMETAA.CG_MGRS_CENT = strtrim(fread(fid,23,'uint8=>char')');
    CMETAA.CG_MGRSCORUL = strtrim(fread(fid,23,'uint8=>char')');
    CMETAA.CG_MGRSCORUR = strtrim(fread(fid,23,'uint8=>char')');
    CMETAA.CG_MGRSCORLR = strtrim(fread(fid,23,'uint8=>char')');
    CMETAA.CG_MGRCORLL = strtrim(fread(fid,23,'uint8=>char')');
    CMETAA.CG_MGRS_CONFIDENCE = str2double(fread(fid,7,'uint8=>char')');
    CMETAA.CG_MGRS_PAD = strtrim(fread(fid,11,'uint8=>char')');
elseif strcmp(CMETAA.CG_MAP_TYPE,'NA')
    CMETAA.CG_MAP_TYPE_BLANK = strtrim(fread(fid,133,'uint8=>char')');
end
CMETAA.CG_SPARE_A = strtrim(fread(fid,144,'uint8=>char')');
CMETAA.CA_CALPA = str2double(fread(fid,7,'uint8=>char')');
CMETAA.WF_SRTFR = str2double(fread(fid,14,'uint8=>char')');
CMETAA.WF_ENDFR = str2double(fread(fid,14,'uint8=>char')');
CMETAA.WF_CHRPRT = str2double(fread(fid,10,'uint8=>char')');
CMETAA.WF_WIDTH = str2double(fread(fid,9,'uint8=>char')');
CMETAA.WF_CENFRQ = str2double(fread(fid,13,'uint8=>char')');
CMETAA.WF_BW = str2double(fread(fid,13,'uint8=>char')');
CMETAA.WF_PRF = str2double(fread(fid,7,'uint8=>char')');
CMETAA.WF_PRI = str2double(fread(fid,9,'uint8=>char')');
CMETAA.WF_CDP = str2double(fread(fid,7,'uint8=>char')');
CMETAA.WF_NUMBER_OF_PULSES = str2double(fread(fid,9,'uint8=>char')');

CMETAA.VPH_COND = strtrim(fread(fid,1,'uint8=>char')');

% //////////////////////////////////////////
% /// CLASSIFICATION: UNCLASSIFIED       ///
% //////////////////////////////////////////


function SDP = rmlindep_sdpt3(SDP)
%% remove linearly dependent constraints
[Atnew,bnew,~,~,~,~,~] = ...
              checkdepconstr(SDP.blk,SDP.At,SDP.b,zeros(length(SDP.b),1),1);
SDP.At  = Atnew;
SDP.b   = bnew;
end


function obj = t3_pTop_func_new(in1,in2,in3)
coefs_tq1_1 = in2(1);
coefs_tq1_2 = in2(4);
coefs_tq1_3 = in2(7);
coefs_tq1_4 = in2(10);
coefs_tq1_5 = in2(13);
coefs_tq1_6 = in2(16);
coefs_tq1_7 = in2(19);
coefs_tq1_8 = in2(22);
coefs_tq1_9 = in2(25);
coefs_tq2_1 = in2(2);
coefs_tq2_2 = in2(5);
coefs_tq2_3 = in2(8);
coefs_tq2_4 = in2(11);
coefs_tq2_5 = in2(14);
coefs_tq2_6 = in2(17);
coefs_tq2_7 = in2(20);
coefs_tq2_8 = in2(23);
coefs_tq2_9 = in2(26);
coefs_tq3_1 = in2(3);
coefs_tq3_2 = in2(6);
coefs_tq3_3 = in2(9);
coefs_tq3_4 = in2(12);
coefs_tq3_5 = in2(15);
coefs_tq3_6 = in2(18);
coefs_tq3_7 = in2(21);
coefs_tq3_8 = in2(24);
coefs_tq3_9 = in2(27);
coefs_tq1_10 = in2(28);
coefs_tq1_11 = in2(31);
coefs_tq2_10 = in2(29);
coefs_tq2_11 = in2(32);
coefs_tq3_10 = in2(30);
coefs_tq3_11 = in2(33);
pinvG3_1 = in1(3);
pinvG3_2 = in1(6);
pinvG3_3 = in1(9);
q0 = in3(1,:);
q1 = in3(2,:);
q2 = in3(3,:);
q3 = in3(4,:);
obj = q0.^2.*(coefs_tq1_1.*pinvG3_1+coefs_tq2_1.*pinvG3_2+coefs_tq3_1.*pinvG3_3)+q1.^2.*(coefs_tq1_5.*pinvG3_1+coefs_tq2_5.*pinvG3_2+coefs_tq3_5.*pinvG3_3)+q2.^2.*(coefs_tq1_8.*pinvG3_1+coefs_tq2_8.*pinvG3_2+coefs_tq3_8.*pinvG3_3)+q3.^2.*(coefs_tq1_10.*pinvG3_1+coefs_tq2_10.*pinvG3_2+coefs_tq3_10.*pinvG3_3)+coefs_tq1_11.*pinvG3_1+coefs_tq2_11.*pinvG3_2+coefs_tq3_11.*pinvG3_3+q0.*q1.*(coefs_tq1_2.*pinvG3_1+coefs_tq2_2.*pinvG3_2+coefs_tq3_2.*pinvG3_3)+q0.*q2.*(coefs_tq1_3.*pinvG3_1+coefs_tq2_3.*pinvG3_2+coefs_tq3_3.*pinvG3_3)+q0.*q3.*(coefs_tq1_4.*pinvG3_1+coefs_tq2_4.*pinvG3_2+coefs_tq3_4.*pinvG3_3)+q1.*q2.*(coefs_tq1_6.*pinvG3_1+coefs_tq2_6.*pinvG3_2+coefs_tq3_6.*pinvG3_3)+q1.*q3.*(coefs_tq1_7.*pinvG3_1+coefs_tq2_7.*pinvG3_2+coefs_tq3_7.*pinvG3_3)+q2.*q3.*(coefs_tq1_9.*pinvG3_1+coefs_tq2_9.*pinvG3_2+coefs_tq3_9.*pinvG3_3);


function test_spm12

% MEM 4gb
% WALLTIME 00:10:00
% DEPENDENCY

% currently (Jan, 2017) SPM12 support for:
% - ft_volumerealign
% - ft_volumedownsample (incl smoothing)
% - private/mni2tal
% - private/tal2mni
% - private/volumesmooth
% - ft_read_mri (nifti_spm, default remains spm8) - based on function deps, not real data
% - private/volumewrite_spm (default remains spm8) - based on function deps, not real data
% - utilities/private/sn2individual (called by ft_warp_apply) - based on function deps, not real data
% - utilities/private/individual2sn (called by ft_warp_apply) - forced use of spm8 since spm_invdef is missing in spm12 (in toolbox/OldSeg)
% to do (function-specific intelligence required):
% - ft_volumenormalise
% - ft_volumesegment

mrifile1 = dccnpath('/home/common/matlab/fieldtrip/data/test/latest/mri/freesurfer/T1.mgz');
mri1     = ft_read_mri(mrifile1);
mri1.coordsys = 'tal'; % I don't think this is technically correct, it should be fsaverage aka mni305

mrifile2 = dccnpath('/home/common/matlab/fieldtrip/data/test/latest/mri/nifti/single_subj_T1.nii');
mri2     = ft_read_mri(mrifile2);
mri2.coordsys = 'mni';

mrifile3 = dccnpath('/home/common/matlab/fieldtrip/data/ftp/test/ctf/Subject01.mri');
mri3     = ft_read_mri(mrifile3);
mri3.coordsys = 'ctf';

%----------------------------- SPM12 -----------------------------------

%ft_convert_coordsys: currently uses OldNorm sub-toolbox (i.e. SPM8)
ft_hastoolbox('spm12',1)
c2a = ft_convert_coordsys(mri3, 'tal', 1);
c2b = ft_convert_coordsys(mri3, 'tal', 2);

try
  rmpath(spm('dir'));
end

%ft_volumerealign: coregistration (used in human ecog tutorial)
cfg               = [];
cfg.method        = 'spm';
cfg.spmversion    = 'spm12';
cfg.spm.cost_fun  = 'nmi';
r12 = ft_volumerealign(cfg, mri1, mri2);

try
  rmpath(spm('dir'));
end

%ft_volumedownsample
tmp            = randn(256,256,256);
mri1.pow        = tmp;
mri1.pow(1)     = 0;
cfg            = [];
cfg.downsample = 2;
cfg.spmversion = 'spm12';
cfg.smooth     = 'no';
d12            = ft_volumedownsample(cfg, mri1);
cfg.smooth     = 5;
d12s           = ft_volumedownsample(cfg, mri1);

try
  rmpath(spm('dir'));
end

%mni2tal and tal2mni
[v, p] = ft_version;
cd(fullfile(p, 'private'));

inpoints  = randn(100,3);
outpoints = mni2tal(inpoints);

try
  rmpath(spm('dir'));
end

inpoints = tal2mni(outpoints);

%----------------------------- SPM8 COMPAT -----------------------------

try
  rmpath(spm('dir'));
end

%ft_volumenormalise
cfg            = [];
cfg.nonlinear  = 'no';
cfg.spmversion = 'spm8';
n8 = ft_volumenormalise(cfg, mri1);

%ft_warp_apply with spm12
elecpos = ft_warp_apply(n8.params, [4 4 4; 1 1 1], 'individual2sn');

try
  rmpath(spm('dir'));
end

%ft_volumesegment
cfg             = [];
cfg.spmversion  = 'spm8';
s8 = ft_volumesegment(cfg, mri1);

%-----------------------------------------------------------------------
% Notes from test_old_spm8:
%
% the following m-files contain a line with 'spm_' and have to be dealt with
%
%./external/bemcp/Makefile
%./spmcalls.txt
%./private/tal2mni.m
%./private/prepare_mesh_segmentation.m
%./private/prepare_dipole_grid.m
%./private/mni2tal.m
%./multivariate/toolboxes/gerven/bayesbrain/examples/html/fmri_bn_demo.html
%./multivariate/toolboxes/gerven/bayesbrain/examples/fmri_bn_demo.m
%./testing/test_bug62.m
%
%%done
%./private/avw_img_read.m
%./fileio/private/avw_img_read.m
%./fileio/read_mri.m
%./fileio/ft_read_mri.m
%
%%done and changed
%./ft_volumesegment.m
%./ft_volumenormalise.m
%./ft_volumedownsample.m
%./private/volumewrite_spm.m
%------------------------------------------------------------------------


function [ out ] = VideoToScoreVideoSkip( video, train, s, w, thresh, skip)
%  VideoToScoreVideoSkip - get component video of video/frame passed in
%--------------------------------------------------------------------------
%   Params: video - should be a height X width X 3 X frames --- array
%           train - histograms of the training images
%           s - the window size that each frame will be split up in to form
%               histograms
%           w - the width of the bins for the RGB color
%               histograms
%           thresh - the cutoff distance threshold used to measure whether
%               or not window histograms are close enough to the training
%               histograms.
%           skip - The frames to skip if vidAllCopy is a video entered
%
%   Returns: out - component video
%--------------------------------------------------------------------------

height = length(video(:,1,1,1));
width = length(video(1,:,1,1));
frames = length(video(1,1,1,:));
H = floor(height/s);
W = floor(width/s);
out = false(H,W,frames);

for i = 1:ceil(frames/skip)
    %display(strcat('frame number: ',num2str((i-1)*skip+1)));
    out(:,:,(i-1)*skip+1) = ImageToScoreArray(video(:,:,:,(i-1)*skip+1), train, s, w, thresh);
    for j = (i-1)*skip+2:min(i*skip, frames)
        out(:,:,j) = out(:,:,(i-1)*skip+1);
    end

end


function msg = mpc_init(s,c)
    apm(s,c,'clear all');

    % load model and data
    apm_load(s,c,'control.apm');
    csv_load(s,c,'control.csv');

    % configure MV / CV
    apm_info(s,c,'MV','Q1');
    apm_info(s,c,'CV','TC');

    % dynamic control
    apm_option(s,c,'apm.imode',6);
    apm_option(s,c,'apm.solver',3);
    apm_option(s,c,'apm.hist_hor',600);

    % tune MV
    % delta MV movement penalty
    apm_option(s,c,'Q1.dcost',1.0e-4);
    % penalize energy use
    apm_option(s,c,'Q1.cost',0.0);
    % limit MV movement each cycle
    apm_option(s,c,'Q1.dmax',50);
    % MV limits
    apm_option(s,c,'Q1.upper',100);
    apm_option(s,c,'Q1.lower',0);

    % tune CV
    % how fast to reach setpoint
    apm_option(s,c,'TC.tau',10);
    % trajectory type
    apm_option(s,c,'TC.tr_init',2);

    % let optimizer use MV
    apm_option(s,c,'Q1.status',1);
    % include CV in objective function
    apm_option(s,c,'TC.status',1);

    % feedback status (whether we have measurements)
    apm_option(s,c,'Q1.fstatus',0);
    apm_option(s,c,'TC.fstatus',1);

    % web-viewer option, update every second
    apm_option(s,c,'apm.web_plot_freq',2);

    msg = 'initialization complete';
end


classdef MSDDetector < handle
    %MSDDETECTOR  Class implementing the MSD (Maximal Self-Dissimilarity) keypoint detector
    %
    % Maximal Self-Dissimilarity Interest Point Detector, as described in
    % [Tombari14].
    %
    % The algorithm implements a novel interest point detector stemming from
    % the intuition that image patches which are highly dissimilar over a
    % relatively large extent of their surroundings hold the property of being
    % repeatable and distinctive. This concept of "contextual
    % self-dissimilarity" reverses the key paradigm of recent successful
    % techniques such as the Local Self-Similarity descriptor and the
    % Non-Local Means filter, which build upon the presence of similar
    % (rather than dissimilar) patches. Moreover, it extends to contextual
    % information the local self-dissimilarity notion embedded in established
    % detectors of corner-like interest points, thereby achieving enhanced
    % repeatability, distinctiveness and localization accuracy.
    %
    % ## References
    % [Tombari14]:
    % > Federico Tombari and Luigi Di Stefano.
    % > "Interest Points via Maximal Self-Dissimilarities".
    % > In Asian Conference on Computer Vision, ACCV 2014.
    %
    % See also: cv.MSDDetector.MSDDetector, cv.FeatureDetector
    %

    properties (SetAccess = private)
        % Object ID
        id
    end

    methods
        function this = MSDDetector(varargin)
            %MSDDETECTOR  The full constructor
            %
            %     obj = cv.MSDDetector()
            %     obj = cv.MSDDetector('OptionName',optionValue, ...)
            %
            % ## Options
            % * __PatchRadius__ Patch radius. default 3
            % * __SearchAreaRadius__ Search Area radius. default 5
            % * __NMSRadius__ Non Maxima Suppression spatial radius. default 5
            % * __NMSScaleRadius__ Non Maxima Suppression scale radius.
            %   default 0
            % * __ThSaliency__ Saliency threshold. default 250.0
            % * __KNN__ Number of nearest neighbors. default 4
            % * __ScaleFactor__ Scale factor for building up the image
            %   pyramid. default 1.25
            % * __NScales__ Number of scales number of scales for building up
            %   the image pyramid (if set to -1, this number is automatically
            %   determined). default -1
            % * __ComputeOrientation__ Flag for associating a canoncial
            %   orientation to each keypoint. default false
            %
            % See also: cv.MSDDetector.detect
            %
            this.id = MSDDetector_(0, 'new', varargin{:});
        end

        function delete(this)
            %DELETE  Destructor
            %
            %     obj.delete()
            %
            % See also: cv.MSDDetector
            %
            if isempty(this.id), return; end
            MSDDetector_(this.id, 'delete');
        end

        function typename = typeid(this)
            %TYPEID  Name of the C++ type (RTTI)
            %
            %     typename = obj.typeid()
            %
            % ## Output
            % * __typename__ Name of C++ type
            %
            typename = MSDDetector_(this.id, 'typeid');
        end
    end

    %% Algorithm
    methods
        function clear(this)
            %CLEAR  Clears the algorithm state
            %
            %     obj.clear()
            %
            % See also: cv.MSDDetector.empty, cv.MSDDetector.load
            %
            MSDDetector_(this.id, 'clear');
        end

        function b = empty(this)
            %EMPTY  Checks if detector object is empty
            %
            %     b = obj.empty()
            %
            % ## Output
            % * __b__ Returns true if the detector object is empty (e.g in the
            %   very beginning or after unsuccessful read).
            %
            % See also: cv.MSDDetector.clear, cv.MSDDetector.load
            %
            b = MSDDetector_(this.id, 'empty');
        end

        function save(this, filename)
            %SAVE  Saves the algorithm parameters to a file
            %
            %     obj.save(filename)
            %
            % ## Input
            % * __filename__ Name of the file to save to.
            %
            % This method stores the algorithm parameters in the specified
            % XML or YAML file.
            %
            % See also: cv.MSDDetector.load
            %
            MSDDetector_(this.id, 'save', filename);
        end

        function load(this, fname_or_str, varargin)
            %LOAD  Loads algorithm from a file or a string
            %
            %     obj.load(fname)
            %     obj.load(str, 'FromString',true)
            %     obj.load(..., 'OptionName',optionValue, ...)
            %
            % ## Input
            % * __fname__ Name of the file to read.
            % * __str__ String containing the serialized model you want to
            %   load.
            %
            % ## Options
            % * __ObjName__ The optional name of the node to read (if empty,
            %   the first top-level node will be used). default empty
            % * __FromString__ Logical flag to indicate whether the input is a
            %   filename or a string containing the serialized model.
            %   default false
            %
            % This method reads algorithm parameters from the specified XML or
            % YAML file (either from disk or serialized string). The previous
            % algorithm state is discarded.
            %
            % See also: cv.MSDDetector.save
            %
            MSDDetector_(this.id, 'load', fname_or_str, varargin{:});
        end

        function name = getDefaultName(this)
            %GETDEFAULTNAME  Returns the algorithm string identifier
            %
            %     name = obj.getDefaultName()
            %
            % ## Output
            % * __name__ This string is used as top level XML/YML node tag
            %   when the object is saved to a file or string.
            %
            % See also: cv.MSDDetector.save, cv.MSDDetector.load
            %
            name = MSDDetector_(this.id, 'getDefaultName');
        end
    end

    %% Features2D: FeatureDetector
    methods
        function keypoints = detect(this, img, varargin)
            %DETECT  Detects keypoints in an image or image set
            %
            %     keypoints = obj.detect(img)
            %     keypoints = obj.detect(imgs)
            %     [...] = obj.detect(..., 'OptionName',optionValue, ...)
            %
            % ## Input
            % * __img__ Image (first variant), 8-bit grayscale or color image.
            % * __imgs__ Image set (second variant), cell array of images.
            %
            % ## Output
            % * __keypoints__ The detected keypoints. In the first variant, a
            %   1-by-N structure array. In the second variant of the method,
            %   `keypoints{i}` is a set of keypoints detected in `imgs{i}`.
            %
            % ## Options
            % * __Mask__ A mask specifying where to look for keypoints
            %   (optional). It must be a logical or 8-bit integer matrix with
            %   non-zero values in the region of interest. In the second
            %   variant, it is a cell-array of masks for each input image,
            %   `masks{i}` is a mask for `imgs{i}`. Not set by default.
            %
            % See also: cv.MSDDetector.MSDDetector
            %
            keypoints = MSDDetector_(this.id, 'detect', img, varargin{:});
        end
    end

end


function [retval] = freesurfer_fread3(fid)

% freesurfer_fread3 - read a 3 byte integer out of a file
%
% [retval] = freesurfer_fread3(fid)
%
% see also freesurfer_write3, freesurfer_read_surf, freesurfer_write_surf
%

b1 = fread(fid, 1, 'uchar') ;
b2 = fread(fid, 1, 'uchar') ;
b3 = fread(fid, 1, 'uchar') ;
retval = bitshift(b1, 16) + bitshift(b2,8) + b3 ;


function [pnt, tri, srf] = read_bv_srf(filename)

% READ_BV_SRF reads a triangulated surface from a BrainVoyager *.srf file
%
% Use as
%   [pnt, tri] = read_bv_srf(filename) or
%   [pnt, tri, srf] = read_bv_srf(filename)

% Copyright (C) 2005, Robert Oostenveld
%
% This file is part of FieldTrip, see http://www.fieldtriptoolbox.org
% for the documentation and details.
%
%    FieldTrip is free software: you can redistribute it and/or modify
%    it under the terms of the GNU General Public License as published by
%    the Free Software Foundation, either version 3 of the License, or
%    (at your option) any later version.
%
%    FieldTrip is distributed in the hope that it will be useful,
%    but WITHOUT ANY WARRANTY; without even the implied warranty of
%    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%    GNU General Public License for more details.
%
%    You should have received a copy of the GNU General Public License
%    along with FieldTrip. If not, see <http://www.gnu.org/licenses/>.
%
% $Id$

% This documentation originates from
%   http://www.brainvoyager.com/BV2000OnlineHelp/BrainVoyagerWebHelp/mergedProjects/FileFormats/BrainVoyager_File_Formats.htm
%
% BYTES DATA TYPE DEFAULT DESCRIPTION
% 4 float 3 version number
% 4 int 0 reserved, must be '0'
% 4 int  NrOfVertices (number of vertices)
% 4 int  NrOfTriangles (number of triangles)
% 4 float 128.0 MeshCenterX
% 4 float 128.0 MeshCenterY
% 4 float 128.0 MeshCenterZ
% NrOfVertices*4 float  VertexX, sequence of X coordinates of all vertices
% NrOfVertices*4 float  VertexY, sequence of Y coordinates of all vertices
% NrOfVertices*4 float  VertexZ, sequence of Z coordinates of all vertices
% NrOfVertices*4 float  NormalX, sequence of X components of all vertex normals
% NrOfVertices*4 float  NormalY, sequence of Y components of all vertex normals
% NrOfVertices*4 float  NormalZ, sequence of Z components of all vertex normals
% 4 float 0.322 R component of convex curvature color (range: 0.0 - 1-0)
% 4 float 0.733 G component of convex curvature color (range: 0.0 - 1-0)
% 4 float 0.980 B component of convex curvature color (range: 0.0 - 1-0)
% 4 float 0.500 Alpha component of convex curvature color (range: 0.0 - 1-0)
% 4 float 0.100 R component of concave curvature color (range: 0.0 - 1-0)
% 4 float 0.240 G component of concave curvature color (range: 0.0 - 1-0)
% 4 float 0.320 B component of concave curvature color (range: 0.0 - 1-0)
% 4 float 0.500 Alpha component of concave curvature color (range: 0.0 - 1-0)
% NrOfVertices*4 int  MeshColor, sequence of color indices of all vertices (*1)
% 4 int  N, number of nearest neighbors of vertex 1
% 4 int  Nearest neighbor 1 of vertex 1
% : :  :
% 4 int  Nearest neighbor N of vertex 1
% :: ::  ::
% 4 int  N, number of nearest neighbors of vertex 'NrOfVertices'
% 4 int  Nearest neighbor 1 of vertex 'NrOfVertices'
% : :  :
% 4 int  Nearest neighbor N of vertex 'NrOfVertices'
% NrOfTriangels*3*4 int  Sequence of three indices to constituting vertices of each triangle
% 4 int  NrOfTriangleStripElements
% NrOfStripElements*4 int  Sequence of strip elements (if NrOfStripElements > 0)

fid = fopen_or_error(filename, 'rb', 'ieee-le');

srf.version_number                                        = fread(fid, 1, 'float');
srf.reserved                                              = fread(fid, 1, 'int'  );
srf.NrOfVertices                                          = fread(fid, 1, 'int'  );
srf.NrOfTriangles                                         = fread(fid, 1, 'int'  );
NrOfVertices  = srf.NrOfVertices;
NrOfTriangles = srf.NrOfTriangles;
srf.MeshCenterX                                           = fread(fid, 1, 'float');
srf.MeshCenterY                                           = fread(fid, 1, 'float');
srf.MeshCenterZ                                           = fread(fid, 1, 'float');
srf.X_coordinates                                         = fread(fid, NrOfVertices, 'float');
srf.Y_coordinates                                         = fread(fid, NrOfVertices, 'float');
srf.Z_coordinates                                         = fread(fid, NrOfVertices, 'float');
srf.X_components                                          = fread(fid, NrOfVertices, 'float');
srf.Y_components                                          = fread(fid, NrOfVertices, 'float');
srf.Z_components                                          = fread(fid, NrOfVertices, 'float');
srf.R_component_of_convex_curvature_color                 = fread(fid, 1, 'float');
srf.G_component_of_convex_curvature_color                 = fread(fid, 1, 'float');
srf.B_component_of_convex_curvature_color                 = fread(fid, 1, 'float');
srf.Alpha_component_of_convex_curvature_color             = fread(fid, 1, 'float');
srf.R_component_of_concave_curvature_color                = fread(fid, 1, 'float');
srf.G_component_of_concave_curvature_color                = fread(fid, 1, 'float');
srf.B_component_of_concave_curvature_color                = fread(fid, 1, 'float');
srf.Alpha_component_of_concave_curvature_color            = fread(fid, 1, 'float');
srf.MeshColor                                             = fread(fid, NrOfVertices, 'int'  );
for i=1:NrOfVertices
  number           = fread(fid, 1, 'int'  );
  srf.neighbour{i} = fread(fid, number, 'int'  );
end
srf.Triangles                                             = fread(fid, [3 NrOfTriangles], 'int'  );
srf.NrOfTriangleStripElements                             = fread(fid, 1, 'int'  );
srf.sequence_of_strip_elements                            = fread(fid, srf.NrOfTriangleStripElements, 'int'  );

fclose(fid);

pnt = [srf.X_coordinates(:) srf.Y_coordinates(:) srf.Z_coordinates(:)];
tri = srf.Triangles' + 1;


function [image_roidb, bbox_means, bbox_stds] = fast_rcnn_prepare_image_roidb(conf, imdbs, roidbs, bbox_means, bbox_stds)
% [image_roidb, bbox_means, bbox_stds] = fast_rcnn_prepare_image_roidb(conf, imdbs, roidbs, cache_img, bbox_means, bbox_stds)
%   Gather useful information from imdb and roidb
%   pre-calculate mean (bbox_means) and std (bbox_stds) of the regression
%   term for normalization
% --------------------------------------------------------
% Fast R-CNN
% Reimplementation based on Python Fast R-CNN (https://github.com/rbgirshick/fast-rcnn)
% Copyright (c) 2015, Shaoqing Ren
% Licensed under The MIT License [see LICENSE for details]
% --------------------------------------------------------

    if ~exist('bbox_means', 'var')
        bbox_means = [];
        bbox_stds = [];
    end

    if ~iscell(imdbs)
        imdbs = {imdbs};
        roidbs = {roidbs};
    end

    imdbs = imdbs(:);
    roidbs = roidbs(:);

    image_roidb = ...
        cellfun(@(x, y) ... // @(imdbs, roidbs)
                arrayfun(@(z) ... //@([1:length(x.image_ids)])
                        struct('image_path', x.image_at(z), 'image_id', x.image_ids{z}, 'im_size', x.sizes(z, :), 'imdb_name', x.name, ...
                        'overlap', y.rois(z).overlap, 'boxes', y.rois(z).boxes, 'class', y.rois(z).class, 'image', [], 'bbox_targets', []), ...
                [1:length(x.image_ids)]', 'UniformOutput', true),...
        imdbs, roidbs, 'UniformOutput', false);

    image_roidb = cat(1, image_roidb{:});

    % enhance roidb to contain bounding-box regression targets
    [image_roidb, bbox_means, bbox_stds] = append_bbox_regression_targets(conf, image_roidb, bbox_means, bbox_stds);
end

function [image_roidb, means, stds] = append_bbox_regression_targets(conf, image_roidb, means, stds)
    % means and stds -- (k+1) * 4, include background class

    num_images = length(image_roidb);
    % Infer number of classes from the number of columns in gt_overlaps
    num_classes = size(image_roidb(1).overlap, 2);
    valid_imgs = true(num_images, 1);
    for i = 1:num_images
       rois = image_roidb(i).boxes;
       [image_roidb(i).bbox_targets, valid_imgs(i)] = ...
           compute_targets(conf, rois, image_roidb(i).overlap);
    end
    if ~all(valid_imgs)
        image_roidb = image_roidb(valid_imgs);
        num_images = length(image_roidb);
        fprintf('Warning: fast_rcnn_prepare_image_roidb: filter out %d images, which contains zero valid samples\n', sum(~valid_imgs));
    end

    if ~(exist('means', 'var') && ~isempty(means) && exist('stds', 'var') && ~isempty(stds))
        % Compute values needed for means and stds
        % var(x) = E(x^2) - E(x)^2
        class_counts = zeros(num_classes, 1) + eps;
        sums = zeros(num_classes, 4);
        squared_sums = zeros(num_classes, 4);
        for i = 1:num_images
           targets = image_roidb(i).bbox_targets;
           for cls = 1:num_classes
              cls_inds = find(targets(:, 1) == cls);
              if ~isempty(cls_inds)
                 class_counts(cls) = class_counts(cls) + length(cls_inds);
                 sums(cls, :) = sums(cls, :) + sum(targets(cls_inds, 2:end), 1);
                 squared_sums(cls, :) = squared_sums(cls, :) + sum(targets(cls_inds, 2:end).^2, 1);
              end
           end
        end

        means = bsxfun(@rdivide, sums, class_counts);
        stds = (bsxfun(@minus, bsxfun(@rdivide, squared_sums, class_counts), means.^2)).^0.5;

        % add background class
        means = [0, 0, 0, 0; means];
        stds = [0, 0, 0, 0; stds];
    end

    % Normalize targets
    for i = 1:num_images
        targets = image_roidb(i).bbox_targets;
        for cls = 1:num_classes
            cls_inds = find(targets(:, 1) == cls);
            if ~isempty(cls_inds)
                image_roidb(i).bbox_targets(cls_inds, 2:end) = ...
                    bsxfun(@minus, image_roidb(i).bbox_targets(cls_inds, 2:end), means(cls+1, :));
                image_roidb(i).bbox_targets(cls_inds, 2:end) = ...
                    bsxfun(@rdivide, image_roidb(i).bbox_targets(cls_inds, 2:end), stds(cls+1, :));
            end
        end
    end
end

function [bbox_targets, is_valid] = compute_targets(conf, rois, overlap)

    overlap = full(overlap);

    [max_overlaps, max_labels] = max(overlap, [], 2);

    % ensure ROIs are floats
    rois = single(rois);

    bbox_targets = zeros(size(rois, 1), 5, 'single');

    % Indices of ground-truth ROIs
    gt_inds = find(max_overlaps == 1);

    if ~isempty(gt_inds)
        % Indices of examples for which we try to make predictions
        ex_inds = find(max_overlaps >= conf.bbox_thresh);

        % Get IoU overlap between each ex ROI and gt ROI
        ex_gt_overlaps = boxoverlap(rois(ex_inds, :), rois(gt_inds, :));

        assert(all(abs(max(ex_gt_overlaps, [], 2) - max_overlaps(ex_inds)) < 10^-4));

        % Find which gt ROI each ex ROI has max overlap with:
        % this will be the ex ROI's gt target
        [~, gt_assignment] = max(ex_gt_overlaps, [], 2);
        gt_rois = rois(gt_inds(gt_assignment), :);
        ex_rois = rois(ex_inds, :);

        [regression_label] = fast_rcnn_bbox_transform(ex_rois, gt_rois);

        bbox_targets(ex_inds, :) = [max_labels(ex_inds), regression_label];
    end

    % Select foreground ROIs as those with >= fg_thresh overlap
    is_fg = max_overlaps >= conf.fg_thresh;
    % Select background ROIs as those within [bg_thresh_lo, bg_thresh_hi)
    is_bg = max_overlaps < conf.bg_thresh_hi & max_overlaps >= conf.bg_thresh_lo;

    % check if there is any fg or bg sample. If no, filter out this image
    is_valid = true;
    if ~any(is_fg | is_bg)
        is_valid = false;
    end
end


function V = vhs(im,varargin)
  % VHS Apply a VHS filter to an image
  %
  % V = vhs(im)
  % V = vhs(im,'ParameterName',ParameterValue,...)
  %
  % Inputs:
  %   im  h by w by c image
  %   Optional:
  %     'VerticalLoop' followed by whether to loop the bent strip vertically
  %     over time and output a sequence of images.
  % Output:
  %   V  h by w by c by f image of (f long sequence of images)
  %

  % must use double
  im = im2double(im);

  looping = false;
  % Map of parameter names to variable names
  params_to_variables = containers.Map( {'VerticalLoop'},{'looping'});
  v = 1;
  iter = 1;
  while v <= numel(varargin)
    param_name = varargin{v};
    if isKey(params_to_variables,param_name)
      assert(v+1<=numel(varargin));
      v = v+1;
      % Trick: use feval on anonymous function to use assignin to this workspace
      feval(@()assignin('caller',params_to_variables(param_name),varargin{v}));
    else
      error('Unsupported parameter: %s',varargin{v});
    end
    v=v+1;
  end

  if looping
    strip_top = 1;
  else
    strip_top = ceil(0.4*size(im,1));
  end

  first = 1;
  while true

    % http://mikeyjam.buzznet.com/user/journal/12237761/tutorial-getting-vhs-tv-effect/
    A = im;
    B = im;
    C = im;
    D = im;
    % exclusion blend like photoshop
    % http://www.deepskycolors.com/archive/2010/04/21/formulas-for-Photoshop-blending-modes.html
    ex = @(T,B) 0.5 - 2.*bsxfun(@times,T-0.5,B-0.5);
    % kill color channels
    A(:,:,1) = 0;
    B(:,:,2) = 0;
    C(:,:,3) = 0;
    % Shift color layers
    nudge = @(f) ceil(f*rand(1)*size(im,2));
    A = A(:,mod(nudge(0.02)+(1:end)-1,end)+1,:);
    B = B(:,mod(nudge(0.02)+(1:end)-1,end)+1,:);
    C = C(:,mod(nudge(0.02)+(1:end)-1,end)+1,:);
    A = A(mod(nudge(0.005)+(1:end)-1,end)+1,:,:);
    B = B(mod(nudge(0.005)+(1:end)-1,end)+1,:,:);
    C = C(mod(nudge(0.005)+(1:end)-1,end)+1,:,:);
    % exclusion blend colored layers and alpha blend with original

    F = D+0.3*(ex(ex(C,B),A)-D);
    N = rand(size(im));

    % inverse mapping function
    bend_w = (2*rand(1)-1)*5;
    bend = @(x,u) [mod(x(:,1)+(1-x(:,2)/max(x(:,2))).^2*bend_w,max(x(:,1))) x(:,2)];
    % maketform arguments
    ndims_in = 2;
    ndims_out = 2;
    tdata = [];
    tform = maketform('custom', 2,2, [], bend, tdata);

    % Bend strip
    strip_h = ceil(1/4*size(im,1));
    strip = mod(strip_top+(1:strip_h)-1,size(im,1))+1;
    F(strip,:,:) = imtransform(F(strip,:,:), tform);

    % overlay gray line
    ol= @(T,B) (T>0.5).*(1-(1-2.*(T-0.5)).*(1-B))+(T<=0.5).*((2.*T).*B);
    G = repmat(0.75,[numel(-1:1) size(F,2) size(F,3)]);
    F(mod(strip_top+(-1:1)-1,size(F,1))+1,:,:) = ...
      ol( F(mod(strip_top+(-1:1)-1,size(F,1))+1,:,:),G);

    % overlay horizontal lines
    L = zeros(size(F));
    L(1:4:end,:,:) = 1;
    L(2:4:end,:,:) = 1;
    L = imfilter(L,fspecial('gaussian',[5 5],1.5),'replicate');
    F = ol(F,L);

    % Fade in random color gradient
    m = rand(1,2)*2-1;
    R = bsxfun(@plus,m(1)*(1:size(F,2)),m(2)*(1:size(F,1))');
    R = (R-min(R(:)))./(max(R(:))-min(R(:)));
    R = gray2rgb(R,colormap(jet(255)));
    F = F+0.05*(ol(F,R)-F);

    % soft light
    sl = @(T,B) (B>0.5).*(1-(1-T).*(1-(B-0.5))) + (B<=0.5).*(T.*(B+0.5));
    F = F + 0.15*(sl(F,N)-F);

    % sharpen
    V(:,:,:,iter) = imsharpen(F);

    %imshow(V(:,:,:,iter));
    %drawnow;

    strip_top = strip_top+round(0.057*size(im,1));
    iter = iter+1;
    if ~looping || strip_top > size(im,1)
      break;
    end

  end
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% QPSK demonstration packet-based transceiver for Chilipepper
% Toyon Research Corp.
% http://www.toyon.com/chilipepper.php
% Created 10/17/2012
% embedded@toyon.com
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% There are two major goals with this core. The first is to find the peak
% of the training sequence and then to subsequently pull out and pack the
% bits. The number of bytes transmitted is in the packet so we extract this
% to determine how many bytes to pull out.
% The second goal is to send these bytes off to the Microblaze processor.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%#codegen
function [byte_out, en_out, s_out, o_out] = ...
    qpsk_rx_correlator(s_i_in, s_q_in)

    persistent counter
    persistent sBuf_i sBuf_q
    persistent oLatch sLatch
    persistent q detPacket
    persistent ip op
    persistent bits symCount byteCount numBytes
    t_i = TB_i;
    t_q = TB_q;
    OS_RATE = 8;
    BIT_TO_BYTE = [1 2 4 8 16 32 64 128]';

    if isempty(counter)
        counter = 0;
        sBuf_i = zeros(1,65);
        sBuf_q = zeros(1,65);
        sLatch = 0;
        oLatch = 0;
        q = 0;
        detPacket = 0;
        ip = 0; op = 0;
        bits = zeros(1,8);
        symCount = 0;
        byteCount = 0;
        numBytes = 1000;
    end
    byte_out = 0;
    en_out = 0;

    % found a packet, now we're ready to write the data out
    if counter == 0 && detPacket == 1
        if s_i_in < 0
            sHard_i_t = -1;
        else
            sHard_i_t = 1;
        end
        if s_q_in < 0
            sHard_q_t = -1;
        else
            sHard_q_t = 1;
        end
        sHard_i = 0; sHard_q = 0;
        switch q
            case 0
                sHard_i = sHard_i_t;
                sHard_q = sHard_q_t;
            case 1
                sHard_i = sHard_q_t;
                sHard_q = -sHard_i_t;
            case 2
                sHard_i = -sHard_i_t;
                sHard_q = -sHard_q_t;
            case 3
                sHard_i = -sHard_q_t;
                sHard_q = sHard_i_t;
        end
        sLatch = sHard_i;
        oLatch = 1;
        bits(symCount*2+1) = (sHard_i+1)/2;
        bits(symCount*2+2) = (sHard_q+1)/2;

        symCount = symCount + 1;
        if symCount >= 4
            byteCount = byteCount + 1;
            symCount = 0;
            byte_out = bits*BIT_TO_BYTE;
            en_out = 1;
            % first byte is number of bytes in payload
            if byteCount == 1
                numBytes = byte_out;
            end
            % if we exceed the packet ID
            if byteCount > 3
                % exit if we've written all the bytes or above reasonable
                % threshold
                if byteCount == numBytes+6 || byteCount > 256
                    detPacket = 0;
                    counter = 1;
                end
            end
        end
    end

    % let's see if we can find a packet. only do so if MCU is ok to rcv packet
    if counter == 0 && detPacket == 0
        sLatch = 0;
        if s_i_in < 0
            ss_i = -1;
        else
            ss_i = 1;
        end
        if s_q_in < 0
            ss_q = -1;
        else
            ss_q = 1;
        end

        sBuf_i = [sBuf_i(2:end) ss_i];
        sBuf_q = [sBuf_q(2:end) ss_q];

        sc_iWithi = sBuf_i*t_i;
        sc_iWithq = sBuf_i*t_q;
        sc_qWithi = sBuf_q*t_i;
        sc_qWithq = sBuf_q*t_q;

        ip = abs(sc_iWithi)+abs(sc_qWithq);
        op = abs(sc_iWithq)+abs(sc_qWithi);

        % we found a packet. While we have frequency offset lock we don't
        % know the phase offset. Here we use the inphase and quadrature
        % phasing to determine how to rotate around the circle
        if ip > 100 % 0 or 180 angle
            if sc_iWithi > 10 && sc_qWithq > 10
                q = 0; % 0 degrees
            else
                q = 2; % 180 degrees;
            end
            detPacket = 1;
        end
        if op > 100
            if sc_iWithq > 10 && sc_qWithi < 10
                q = 3; % 90 degrees
            else
                q = 1; % 270 degrees;
            end
            detPacket = 1;
        end
        oLatch = ip+op;
        symCount = 0;
        byteCount = 0;
        numBytes = 1000;
    end

    s_out = sLatch;
    o_out = oLatch;

    % only pull data once every OS_RATE clocks
    counter = counter + 1;
    if counter >= OS_RATE
        counter = 0;
    end
end


function M = rmPlotGUI_getModel(view, roi, allTimePoints, preserveCoords)
% retrieve the model data for the specified retinotopy model, in a struct M.
%
%  M = rmPlotGUI_getModel(view, roi, allTimePoints, [preserveCoords])
%
% The M structure will reside as the GUI's UserData, and contain a compact
% description of both the model and the current state of the GUI. I broke
% off the accessor function, in case anyone wants to try to do command-line
% analyses.
%
% ras, 11/2008; broken off into its own function.
if notDefined('preserveCoords'), preserveCoords = 1;                end

% load file with data
rmFile = viewGet(view, 'rmFile');
if isempty(rmFile),
    fprintf('[%s]:No file selected\n', mfilename);
    return;
end;

% load model
try
    model = viewGet(view, 'rmModel');
catch
    model = [];
end;
if isempty(model),
    load(viewGet(view, 'rmFile'), 'model');
    view  = viewSet(view, 'rmModel', model);
    model = viewGet(view, 'rmModel');
end;

% load params
try
    params = viewGet(view, 'rmParams');
catch
    params = [];
end;
params = rmRecomputeParams(view, params, allTimePoints);

modelNames = viewGet(view, 'rmModelNames');

% initialize the M struct with obvious fields
M.roi = roi;
M.model    = model;
M.modelNum = 1;
M.params = params;
M.modelNames = modelNames;
M.dataType = getDataTypeName(view);
M.viewType = view.viewType;

M.prevVoxel = 1;  % this keeps track of the last selected voxel, to detect changes

% get time series and roi-coords
[M.tSeries, M.coords, M.params] = rmLoadTSeries(view, params, roi, preserveCoords);

% detrend
% get/make trends
verbose = false;
trends  = rmMakeTrends(params);
%if isfield(M.params.analysis,'allnuisance')
%    trends = [trends M.params.analysis.allnuisance];
%end

% recompute
b = pinv(trends)*M.tSeries;
M.tSeries = M.tSeries - trends*b;
nt = size(trends,2);

% make x-axis for time series plot
nFramesInd = [M.params.stim(:).nFrames]./[M.params.stim(:).nUniqueRep];
TR = [M.params.stim(:).framePeriod];
nScans = length(M.params.stim);

x = (0:nFramesInd(1)-1)'.*TR(1);
for n=2:nScans,
    timend = x(end);
    % For scans 2:end, we need to start the indexing at 1, not 0, otherwise
    % the first time point of scan 2 and the last time point of scan 1 will
    % have the same x value. We do not want this.
    % x = [x; ((0:nFramesInd(n)-1)'.*TR(n))+timend];
    x = [x; ((1:nFramesInd(n))'.*TR(n))+timend];

end;
% this does not give the correct separator locations between scans
% M.sepx = cumsum(nFramesInd-1) .* TR;
% rather we want this:
M.sepx = (cumsum(nFramesInd)-1) .* TR;
M.x    = x;

return;

%% if we got here, we haven't changed the voxel:
% we can adjust the rfParams, *if* the option is selected...

% test whether the 'adjust PRF' option is selected
if isequal( get(M.ui.movePRF, 'Checked'), 'on' )
	% either manually move the pRF according to slider values...
	mrvSliderSet(M.ui.moveX, 'Visible', 'on');
    mrvSliderSet(M.ui.moveY, 'Visible', 'on');
	mrvSliderSet(M.ui.moveSigma, 'Visible', 'on');
    rfParams(1) = get(M.ui.moveX.sliderHandle, 'Value');
    rfParams(2) = get(M.ui.moveY.sliderHandle, 'Value');
	rfParams(3) = get(M.ui.moveSigma.sliderHandle, 'Value');
	rfParams(5) = rfParams(3);   % circular case

else
	% ... or use stored values  (and keep the sliders hidden)
    mrvSliderSet(M.ui.moveX, 'Visible', 'off');
    mrvSliderSet(M.ui.moveY, 'Visible', 'off');
    mrvSliderSet(M.ui.moveSigma, 'Visible', 'off');

end

return


function dat=nj_tseries(ncRef,var,loni,lati,varargin)
% NJ_TSERIES Interpolate time series at lon,lat points from CF model output
% Usage:  dat=nj_tseries(uri,var,lon,lat,varargin)
% Inputs:
%    ncRef = netcdf file name, dods url, or ncgeodataset object
%    var = variable name (string) (e.g. 'salt');
%    lon = vector of longitudes where time series are desired
%    lat = vector of latitudes  where time series are desired
% Optional additional parameter pairs
%    'method' =   'nearest' or 'linear'
%    'layer' =  number of layer to extract
%    'itime' =   indices of time to extract
%    'ele' =    connectivity array (required for non structured grids)
%
% Unstructured Grid Example:  surface layer salinity for 1st 100 time steps
% url='http://www.smast.umassd.edu:8080/thredds/dodsC/fvcom/hindcasts/30yr_gom3'
% dat=nj_tseries(url,'salinity',-70.5,42.5,'method','nearest',...
%     'layer',1,'itime',1:100,'ele',1);
%
% Structured Grid Example:  surface layer salinity for 1st 100 time steps
% url='http://geoport.whoi.edu/thredds/dodsC/coawst_2_2/fmrc/coawst_2_2_best.ncd'
% dat=nj_tseries(url,'salt',-70.5,42.5,'method','nearest',...
%     'layer',16,'itime',1:100);

% Outputs:
%      dat.vals = data values
%      dat.time = time values
%      dat.ii= i value
%      dat.jj= j value

% Rich Signell (rsignell@usgs.gov)

if (isa(ncRef, 'ncgeodataset')) %check for ncgeodataset Object
  nc = ncRef;
else
  % open CF-compliant NetCDF File as a Common Data Model (CDM) "Grid Dataset"
  nc = ncgeodataset(ncRef);
end
vart=nc.geovariable(var);
lon=nc.data(vart.getlonname);
lat=nc.data(vart.getlatname);

while ~isempty(varargin),
  switch lower(varargin{1}),
    case 'method',
      method=varargin{2};
    case 'layer',
      layer=varargin{2};
    case 'itime',
      itime=varargin{2};
    case 'ele',
      ele=varargin{2};
    otherwise,
      error(['Can''t understand property:' varargin{1}]);
  end
  varargin([1 2])=[];
end
if ~exist('method','var'),method='nearest';end
jdmat=nj_time(ncRef,var); % returns [] if no time variable exists
if ~exist('itime','var'),
  if ~isempty(jdmat)
    itime=1:length(jdmat);
  end
end

ntime=length(itime);
npoint=length(loni);
% initialize
u=zeros(ntime,npoint);
lono=zeros(npoint);
lato=zeros(npoint);
inear=zeros(npoint);
jnear=zeros(npoint);

switch method
  case 'nearest'  % find closest point
    for k=1:npoint
      if exist('ele','var');  % unstructured grid
        ind=nearxy(double(lon(:)),double(lat(:)),loni(k),lati(k));
        lono(k)=lon(ind);
        lato(k)=lat(ind);
        fprintf('extracting point %d:lon=%f,lat=%f\n',k,lono(k),lato(k));

        if ~exist('itime','var');
          u(:,k)=nc{var}(ind);  % no time variable, e.g. bathymetry
        elseif (exist('itime','var') && ~exist('layer','var'))
          u(:,k)=squeeze(nc{var}(itime,ind));
        elseif (exist('itime','var') &&  exist('layer','var'))
          u(:,k)=squeeze(nc{var}(itime,layer,ind));
          dat.layer=layer;
        else
          disp('invalid arguments');return
        end
        dat.ii(k)=ind;
      else   % structured grid
        if isvector(lon), [lon,lat]=meshgrid(lon,lat);end;
        ind=nearxy(double(lon(:)),double(lat(:)),loni(k),lati(k));
        [jj,ii]=ind2ij(double(lon),ind);
        lono(k)=lon(jj,ii);
        lato(k)=lat(jj,ii);
        fprintf('extracting point %d:lon=%f,lat=%f\n',k,lono(k),lato(k));
        if ~exist('itime','var');
          u(:,k)=nc{var}(jj,ii);  % no time variable, e.g. bathymetry
        elseif (exist('itime','var') && ~exist('layer','var'))
          u(:,k)=squeeze(nc{var}(itime,jj,ii));
        elseif (exist('itime','var') &&  exist('layer','var'))
          u(:,k)=squeeze(nc{var}(itime,layer,jj,ii));
          dat.layer=layer;
        else
          disp('invalid arguments');return
        end
        dat.ii(k)=ii;
        dat.jj(k)=jj;
      end
    end
  case 'linear'  % interpolate from surrounding points
    if exist('ele','var');  % unstructured grid
      error(' ''linear'' interpolation not working yet for unstructured grid. Use ''nearest'' ')
    else % structured grid
      lono=loni;
      lato=lati;
      if isvector(lon), [lon,lat]=meshgrid(lon,lat);end;
      [n,m]=size(lon);
      [ii,jj]=meshgrid(1:m,1:n);
      F1=TriScatteredInterp(double(lon(:)),double(lat(:)),ii(:));
      ivar=F1(loni(:),lati(:));
      F2=TriScatteredInterp(double(lon(:)),double(lat(:)),jj(:));
      jvar=F2(loni(:),lati(:));
      for k=1:length(loni);
        fprintf('interpolating at point %d:lon=%f,lat=%f\n',k,loni(k),lati(k));
        i0=floor(ivar(k));
        ifrac=ivar(k)-i0;
        j0=floor(jvar(k));
        jfrac=jvar(k)-j0;
        if ~exist('itime','var'); % 2D (no time dimension)
          uall=nc{var}(j0:j0+1,i0:i0+1);
          u1=uall(1,1);
          u2=uall(1,2);
          u3=uall(2,1);
          u4=uall(2,2);
        elseif (exist('itime','var') && ~exist('layer','var'))
          uall=squeeze(nc{var}(itime,j0:j0+1,i0:i0+1));
          u1=uall(:,1,1);
          u2=uall(:,1,2);
          u3=uall(:,2,1);
          u4=uall(:,2,2);
        elseif (exist('itime','var') &&  exist('layer','var'))
          uall=squeeze(nc{var}(itime,layer,j0:j0+1,i0:i0+1));
          u1=uall(:,1,1);
          u2=uall(:,1,2);
          u3=uall(:,2,1);
          u4=uall(:,2,2);
          dat.layer=layer;
        else               % 3D (2D with time dimension)
          disp('invalid arguments');return
        end
        dat.ii=ivar;
        dat.jj=jvar;
        ua=u1+(u2-u1)*ifrac;
        ub=u3+(u4-u3)*ifrac;
        u(:,k)=ua+jfrac*(ub-ua);
      end
    end
end
dat.vals=u;
dat.lon=lono;
dat.lat=lato;
if ~isempty(jdmat)
  dat.time=jdmat(itime);
end


function gX = biasKernGradX(kern, X, X2)

% BIASKERNGRADX Gradient of BIAS kernel with respect to input locations.
% FORMAT
% DESC computes the gradident of the bias
% kernel with respect to the input positions where both the row
% positions and column positions are provided separately.
% ARG kern : kernel structure for which gradients are being
% computed.
% ARG x1 : row locations against which gradients are being computed.
% ARG x2 : column locations against which gradients are being computed.
% RETURN g : the returned gradients. The gradients are returned in
% a matrix which is numData2 x numInputs x numData1. Where numData1 is
% the number of data points in X1, numData2 is the number of data
% points in X2 and numInputs is the number of input
% dimensions in X.
%
% SEEALSO biasKernParamInit, kernGradX, biasKernDiagGradX
%
% COPYRIGHT : Neil D. Lawrence, 2004, 2005, 2006

% KERN

gX = zeros(size(X2, 1), size(X2, 2), size(X, 1));


function g = kernGradient(kern, x, varargin)

% KERNGRADIENT Compute the gradient wrt the kernel's parameters.
% FORMAT
% DESC computes the gradient of functions with respect to the
% kernel's parameters. As well as the kernel structure and the
% input positions, the user provides a matrix PARTIAL which gives
% the partial derivatives of the function with respect to the
% relevant elements of the kernel matrix.
% ARG kern : the kernel structure for which the gradients are being
% computed.
% ARG x : the input locations for which the gradients are being
% computed.
% ARG partial : matrix of partial derivatives of the function of
% interest with respect to the kernel matrix. The argument takes
% the form of a square matrix of dimension  numData, where numData is
% the number of rows in X.
% RETURN g : gradients of the function of interest with respect to
% the kernel parameters. The ordering of the vector should match
% that provided by the function kernExtractParam.
%
% FORMAT
% DESC computes the derivatives as above, but input locations are
% now provided in two matrices associated with rows and columns of
% the kernel matrix.
% ARG kern : the kernel structure for which the gradients are being
% computed.
% ARG x1 : the input locations associated with the rows of the
% kernel matrix.
% ARG x2 : the input locations associated with the columns of the
% kernel matrix.
% ARG partial : matrix of partial derivatives of the function of
% interest with respect to the kernel matrix. The matrix should
% have the same number of rows as X1 and the same number of columns
% as X2 has rows.
% RETURN g : gradients of the function of interest with respect to
% the kernel parameters.
%
% SEEALSO kernDiagGradient, kernGradX

% KERN

fhandle = str2func([kern.type 'KernGradient']);

% varargin contains (optionally) x2 and covGrad.
g = fhandle(kern, x, varargin{:});

% Check if parameters are being optimised in a transformed space.
factors = kernFactors(kern, 'gradfact');
g(factors.index) = g(factors.index).*factors.val;


function r1 = compute_r1_multiCam(good_image, junk_image, index, queryCam, testCam)
good_cam = testCam(good_image);
good_cam_uni = unique(good_cam);
r1 = ones(1, 6)-3;

% on the same camera
good_cam_now = queryCam;
ngood = length(junk_image)-1;
junk_image_now = [good_image; index(1)];
good_image_now = setdiff(junk_image, index(1));
good_now = 0;
for n = 1:length(index)
    flag = 0;
    if ngood == 0
        r1(good_cam_now) = -1;
        break;
    end
    if ~isempty(find(good_image_now == index(n), 1))
        flag = 1; % good image
        good_now = good_now+1;
    end
    if ~isempty(find(junk_image_now == index(n), 1))
        continue; % junk image
    end
    if flag == 0
        r1(good_cam_now) = 0;
        break;
    end
    if flag == 1%good
        r1(good_cam_now) = 1;
        break;
    end
end

for k = 1:length(good_cam_uni)
    good_cam_now = good_cam_uni(k);
    ngood = length(find(good_cam == good_cam_now));
    pos_junk = find(good_cam ~= good_cam_now);
    junk_image_now = [junk_image; good_image(pos_junk)];
    pos_good = find(good_cam == good_cam_now);
    good_image_now = good_image(pos_good);
    for n = 1:length(index)
        flag = 0;
        if ngood == 0
            r1(good_cam_now) = -1;
            break;
        end
        if ~isempty(find(good_image_now == index(n), 1))
            flag = 1; % good image
        end
        if ~isempty(find(junk_image_now == index(n), 1))
            continue; % junk image
        end

        if flag == 0
            r1(good_cam_now) = 0;
            break;
        end
        if flag == 1%good
            r1(good_cam_now) = 1;
            break;
        end
    end
end

end


%io_readlcmcoord_getBackground.m
%Jamie Near, McGill University 2014.
%
% USAGE:
% out = io_readlcmcoord_getBackground(filename,part)
%
% DESCRIPTION:
% Reads a LCModel .coord file and extracts the desired part.
%
% INPUTS:
% filename   = filename of the LCModel .coord file.
% part       = Which part of the .coord file to extract - 'bg' extracts the
%             LCModel baseline signal, 'sp' extracts the spectrum, and
%             'fit' extracts the fit.
%
% OUTPUTS:
% out        = Desired background component in simplified FID-A structure format.

function [out]=io_readlcmcoord_getBackground(filename,part)

fid=fopen(filename);
linenum=1;
line=fgets(fid)

%READ PPM AXIS
ppmstr='points on ppm-axis ='
ppm_index=findstr(line,ppmstr);
while isempty(ppm_index)
    line=fgets(fid);
    ppm_index=findstr(line,ppmstr);
end

Npts=str2num(line(2:5))

line=fgets(fid);
while linenum<=(Npts/10)
    [A,count, errmsg, nextindex] = sscanf(line, '%f', inf);
    A
    ppm((linenum-1)*10+1:linenum*10,1)=A;
    linenum=linenum+1;
    line=fgets(fid);
end

%GET BACKGROUND

linenum=1;
switch part
    case 'bg'
        bgstr='NY background values follow'
    case 'sp'
        bgstr='NY phased data points follow'
    case 'fit'
        bgstr='NY points of the fit to the data follow'
    otherwise
        error('ERROR:  part not found');
end
bg_index=findstr(line,bgstr);
while isempty(bg_index)
    line=fgets(fid);
    bg_index=findstr(line,bgstr);
end

line=fgets(fid);
while linenum<=(Npts/10)
    [A,count, errmsg, nextindex] = sscanf(line, '%f', inf);
    A;
    bg((linenum-1)*10+1:linenum*10,1)=A;
    linenum=linenum+1;
    line=fgets(fid);
end

out.ppm=ppm;
out.specs=bg;


function [total_boxes points] = detect_face(img,minsize,PNet,RNet,ONet,threshold,fastresize,factor)
	%im: input image
	%minsize: minimum of faces' size
	%pnet, rnet, onet: caffemodel
	%threshold: threshold=[th1 th2 th3], th1-3 are three steps's threshold
	%fastresize: resize img from last scale (using in high-resolution images) if fastresize==true
	factor_count=0;
	total_boxes=[];
	points=[];
	h=size(img,1);
	w=size(img,2);
	minl=min([w h]);
    img=single(img);
	if fastresize
		im_data=(single(img)-127.5)*0.0078125;
    end
    m=12/minsize;
	minl=minl*m;
	%creat scale pyramid
    scales=[];
	while (minl>=12)
		scales=[scales m*factor^(factor_count)];
		minl=minl*factor;
		factor_count=factor_count+1;
	end
	%first stage
	for j = 1:size(scales,2)
		scale=scales(j);
		hs=ceil(h*scale);
		ws=ceil(w*scale);
		if fastresize
			im_data=imResample(im_data,[hs ws],'bilinear');
		else
			im_data=(imResample(img,[hs ws],'bilinear')-127.5)*0.0078125;
		end
		PNet.blobs('data').reshape([hs ws 3 1]);
		out=PNet.forward({im_data});
		boxes=generateBoundingBox(out{2}(:,:,2),out{1},scale,threshold(1));
		%inter-scale nms
		pick=nms(boxes,0.5,'Union');
		boxes=boxes(pick,:);
		if ~isempty(boxes)
			total_boxes=[total_boxes;boxes];
		end
	end
	numbox=size(total_boxes,1);
	if ~isempty(total_boxes)
		pick=nms(total_boxes,0.7,'Union');
		total_boxes=total_boxes(pick,:);
		regw=total_boxes(:,3)-total_boxes(:,1);
		regh=total_boxes(:,4)-total_boxes(:,2);
		total_boxes=[total_boxes(:,1)+total_boxes(:,6).*regw total_boxes(:,2)+total_boxes(:,7).*regh total_boxes(:,3)+total_boxes(:,8).*regw total_boxes(:,4)+total_boxes(:,9).*regh total_boxes(:,5)];
		total_boxes=rerec(total_boxes);
		total_boxes(:,1:4)=fix(total_boxes(:,1:4));
		[dy edy dx edx y ey x ex tmpw tmph]=pad(total_boxes,w,h);
	end
	numbox=size(total_boxes,1);
	if numbox>0
		%second stage
 		tempimg=zeros(24,24,3,numbox);
		for k=1:numbox
			tmp=zeros(tmph(k),tmpw(k),3);
			tmp(dy(k):edy(k),dx(k):edx(k),:)=img(y(k):ey(k),x(k):ex(k),:);
			tempimg(:,:,:,k)=imResample(tmp,[24 24],'bilinear');
		end
        tempimg=(tempimg-127.5)*0.0078125;
		RNet.blobs('data').reshape([24 24 3 numbox]);
		out=RNet.forward({tempimg});
		score=squeeze(out{2}(2,:));
		pass=find(score>threshold(2));
		total_boxes=[total_boxes(pass,1:4) score(pass)'];
		mv=out{1}(:,pass);
		if size(total_boxes,1)>0
			pick=nms(total_boxes,0.7,'Union');
			total_boxes=total_boxes(pick,:);
            total_boxes=bbreg(total_boxes,mv(:,pick)');
            total_boxes=rerec(total_boxes);
		end
		numbox=size(total_boxes,1);
		if numbox>0
			%third stage
			total_boxes=fix(total_boxes);
			[dy edy dx edx y ey x ex tmpw tmph]=pad(total_boxes,w,h);
            tempimg=zeros(48,48,3,numbox);
			for k=1:numbox
				tmp=zeros(tmph(k),tmpw(k),3);
				tmp(dy(k):edy(k),dx(k):edx(k),:)=img(y(k):ey(k),x(k):ex(k),:);
				tempimg(:,:,:,k)=imResample(tmp,[48 48],'bilinear');
			end
			tempimg=(tempimg-127.5)*0.0078125;
			ONet.blobs('data').reshape([48 48 3 numbox]);
			out=ONet.forward({tempimg});
			score=squeeze(out{3}(2,:));
			points=out{2};
			pass=find(score>threshold(3));
			points=points(:,pass);
			total_boxes=[total_boxes(pass,1:4) score(pass)'];
			mv=out{1}(:,pass);
			w=total_boxes(:,3)-total_boxes(:,1)+1;
            h=total_boxes(:,4)-total_boxes(:,2)+1;
            points(1:5,:)=repmat(w',[5 1]).*points(1:5,:)+repmat(total_boxes(:,1)',[5 1])-1;
            points(6:10,:)=repmat(h',[5 1]).*points(6:10,:)+repmat(total_boxes(:,2)',[5 1])-1;
			if size(total_boxes,1)>0
				total_boxes=bbreg(total_boxes,mv(:,:)');
                pick=nms(total_boxes,0.7,'Min');
				total_boxes=total_boxes(pick,:);
                points=points(:,pick);
			end
		end
    end
end


function [fname] = globedems(latlim,lonlim)

    %GLOBEDEMS (30-arc-sec resolution) DEM file names
    %
    % fname = GLOBEDEMS(LATLIM,LONLIM) returns a cellarray of the file
    % names covering the geographic region for GLOBEDEM digital elevation maps.
    % The region is specified by scalar latitude and longitude points, or two
    % element vectors of latitude and longitude limits in units of degrees.
    %
    % The data and some documentation is available over the World-Wide-Web from
    % <http://www.ngdc.noaa.gov/seg/topo/globe.shtml>. The data are available
    % by anonymous ftp from <ftp://ftp.ngdc.noaa.gov/GLOBE_DEM/data/elev/>. The
    % web site also sells copies of the data on CD-ROM.
    %
    % See also: GLOBEDEM

    %  Copyright 1996-2000 Systems Planning and Analysis, Inc. and The MathWorks, Inc.
    %  Written by:  A. Kim, W. Stumpf, L. Job
    %  $Revision: 1399 $    $Date: 2006-08-11 11:19:27 +0200 (Fr, 11 Aug 2006) $

    if nargin~=2
        error('Incorrect number of arguments')
    end

    % ensure row vectors
    latlim = latlim(:)';
    lonlim = lonlim(:)';

    if  isequal(size(latlim),[1 1])
        latlim = latlim*[1 1];
    elseif ~isequal(size(latlim),[1 2])
        error('Latitude limit input must be a scalar or 2 element vector')
    end

    if isequal(sort(size(lonlim)),[1 1])
        lonlim = lonlim*[1 1];
    elseif ~isequal(sort(size(lonlim)),[1 2])
        error('Longitude limit input must be a scalar or 2 element vector')
    end

    % read names and bounding rectangle limits

    [fnames,YMIN,YMAX,XMIN,XMAX,rtile,ctile] = textread('globedems.dat','%s %d %d %d %d %d %d');

    % case where dateline is not crossed
    if lonlim(1) <= lonlim(2)
        do = ...
            find( ...
            (...
            (latlim(1) <= YMIN & latlim(2) >= YMAX) | ... % tile is completely within region
            (latlim(1) >= YMIN & latlim(2) <= YMAX) | ... % region is completely within tile
            (latlim(1) >  YMIN & latlim(1) <  YMAX) | ... % min of region is on tile
            (latlim(2) >  YMIN & latlim(2) <  YMAX)   ... % max of region is on tile
            ) ...
            &...
            (...
            (lonlim(1) <= XMIN & lonlim(2) >= XMAX) | ... % tile is completely within region
            (lonlim(1) >= XMIN & lonlim(2) <= XMAX) | ... % region is completely within tile
            (lonlim(1) >  XMIN & lonlim(1) <  XMAX) | ... % min of region is on tile
            (lonlim(2) >  XMIN & lonlim(2) <  XMAX)   ... % max of region is on tile
            )...
            );
    end

    % case where the dateline is crossed
    if lonlim(1) > lonlim(2)
        lmin = lonlim(1); lmax = lonlim(2);
        lonlim(2) = 180;
        % do eastern side of the dateline first
        doEAST = ...
            find( ...
            (...
            (latlim(1) <= YMIN & latlim(2) >= YMAX) | ... % tile is completely within region
            (latlim(1) >= YMIN & latlim(2) <= YMAX) | ... % region is completely within tile
            (latlim(1) >  YMIN & latlim(1) <  YMAX) | ... % min of region is on tile
            (latlim(2) >  YMIN & latlim(2) <  YMAX)   ... % max of region is on tile
            ) ...
            &...
            (...
            (lonlim(1) <= XMIN & lonlim(2) >= XMAX) | ... % tile is completely within region
            (lonlim(1) >= XMIN & lonlim(2) <= XMAX) | ... % region is completely within tile
            (lonlim(1) >  XMIN & lonlim(1) <  XMAX) | ... % min of region is on tile
            (lonlim(2) >  XMIN & lonlim(2) <  XMAX)   ... % max of region is on tile
            )...
            );
        % do western side of the dateline second
        lonlim(1) = -180; lonlim(2) = lmax;
        doWEST = ...
            find( ...
            (...
            (latlim(1) <= YMIN & latlim(2) >= YMAX) | ... % tile is completely within region
            (latlim(1) >= YMIN & latlim(2) <= YMAX) | ... % region is completely within tile
            (latlim(1) >  YMIN & latlim(1) <  YMAX) | ... % min of region is on tile
            (latlim(2) >  YMIN & latlim(2) <  YMAX)   ... % max of region is on tile
            ) ...
            &...
            (...
            (lonlim(1) <= XMIN & lonlim(2) >= XMAX) | ... % tile is completely within region
            (lonlim(1) >= XMIN & lonlim(2) <= XMAX) | ... % region is completely within tile
            (lonlim(1) >  XMIN & lonlim(1) <  XMAX) | ... % min of region is on tile
            (lonlim(2) >  XMIN & lonlim(2) <  XMAX)   ... % max of region is on tile
            )...
            );
        % concatenate indices
        do = [doEAST doWEST];
    end

    if ~isempty(do)
        fname = fnames(do);
    else
        fname = [];
    end


function edgeBoxesSweeps()
% Parameter sweeps for Edges Boxes object proposals.
%
% Running the parameter sweeps requires altering internal flags.
% The sweeps are not well documented, use at your own discretion.
%
% Structured Edge Detection Toolbox      Version 3.01
% Code written by Piotr Dollar and Larry Zitnick, 2014.
% Licensed under the MSR-LA Full Rights License [see license.txt]

% define parameter sweeps
rt = [fileparts(mfilename('fullpath')) filesep];
expNms = {'alpha','beta','eta','minScore','edgeMinMag','edgeMergeThr',...
  'clusterMinMag','maxAspectRatio','minBoxArea','gamma','kappa'};
expNms=expNms(1:end); opts=createExp(rt,expNms); maxn=inf;

% run training and testing jobs
jobs = createJobs(rt,opts,maxn);
tic, for i=1:length(jobs), edgeBoxes(jobs{i}{:}); end; toc

% plot all results
for e=1:length(expNms)
  eval={'data',boxesData('split','val'),'names',{opts{e}.name},...
    'resDir',[rt 'boxes/sweeps/'],'maxn',maxn,'fName',expNms{e}};
  boxesEval(eval{:},'thrs',.7);
  ar=boxesEval(eval{:},'thrs',.5:.05:1,'cnts',1000);
  ar=squeeze(mean(ar,2)); [~,i]=max(ar); disp(opts{e}(i))
end

end

function jobs = createJobs( rt, opts, maxn )
% create jobs
M='models/forest/modelBsds'; M=load(M); M=M.model; M.opts.nThreads=1;
data=boxesData('split','val'); fs=data.imgs(1:min(end,maxn));
opts=[opts{:}]; N=length(opts); jobs=cell(1,N); D=zeros(1,N);
for e=1:N, opts(e).name=[rt 'boxes/sweeps/' opts(e).name '-val.mat']; end
for e=1:N, D(e)=exist(opts(e).name,'file')==2; jobs{e}={fs,M,opts(e)}; end
[~,K]=unique({opts.name},'stable'); D=D(K); jobs=jobs(K); jobs=jobs(~D);
fprintf('nJobs = %i\n',length(jobs));
end

function opts = createExp( rt, expNm )

% if expNm is a cell, call recursively and return
if( iscell(expNm) )
  N=length(expNm); opts=cell(1,N);
  for e=1:N, opts{e}=createExp(rt,expNm{e}); end; return;
end

% setup opts
opts=edgeBoxes(); opts.minScore=0;
N=100; optsDefault=opts; opts=opts(ones(1,N));
switch expNm
  case 'alpha'
    vs=45:5:75; N=length(vs);
    for e=1:N, opts(e).alpha=vs(e)/100; end
  case 'beta'
    vs=60:5:90; N=length(vs);
    for e=1:N, opts(e).beta=vs(e)/100; end
  case 'eta'
    vs=0:5; N=length(vs);
    for e=1:N, opts(e).eta=1-vs(e)/10000; end
  case 'minScore'
    vs=[0 5 10 25 50 100]; N=length(vs);
    for e=1:N, opts(e).minScore=vs(e)/1000; end
  case 'edgeMinMag'
    vs=[0 50 100 200 400]; N=length(vs);
    for e=1:N, opts(e).edgeMinMag=vs(e)/1000; end
  case 'edgeMergeThr'
    vs=[25 50 100 200 400]; N=length(vs);
    for e=1:N, opts(e).edgeMergeThr=vs(e)/100; end
  case 'clusterMinMag'
    vs=[0 50 100 200 400]; N=length(vs);
    for e=1:N, opts(e).clusterMinMag=vs(e)/100; end
  case 'maxAspectRatio'
    vs=1:5; N=length(vs);
    for e=1:N, opts(e).maxAspectRatio=vs(e); end
  case 'minBoxArea'
    vs=[100 250 500 1000 2500 5000]; N=length(vs);
    for e=1:N, opts(e).minBoxArea=vs(e); end
  case 'gamma'
    vs=[25 50 100 200 400 10000]; N=length(vs);
    for e=1:N, opts(e).gamma=vs(e)/100; end
  case 'kappa'
    vs=50:25:200; N=length(vs);
    for e=1:N, opts(e).kappa=vs(e)/100; end
  otherwise, error('invalid exp: %s',expNm);
end

% produce final set of opts and find default opts
O=1:N; opts=opts(O); d=0;
for e=1:N, if(isequal(optsDefault,opts(e))), d=e; break; end; end
if(d==0), disp(expNm); assert(false); end; opts(d).name='Default';
for e=1:N, if(e~=d), opts(e).name=[expNm int2str2(vs(e),5)]; end; end

end


function [hog_data, valid_inds, vid_id] = Read_HOG_files_small(hog_files, hog_data_dir, num_samples)

    hog_data = [];
    vid_id = {};

    feats_filled = 0;

    curr_data_buff = [];

    for i=1:numel(hog_files)

        hog_file = [hog_data_dir, hog_files(i).name];

        fprintf('%d %s\n', i, hog_file);

        f = fopen(hog_file, 'r');

        curr_ind = 0;

        while(~feof(f))

            if(i == 1 && curr_ind == 0)
                num_cols = fread(f, 1, 'int32');
                if(isempty(num_cols))
                    break;
                end

                num_rows = fread(f, 1, 'int32');
                num_chan = fread(f, 1, 'int32');

                curr_ind = curr_ind + 1;

                % preallocate some space
                if(curr_ind == 1)
                    curr_data_buff = zeros(5000, 1 + num_rows * num_cols * num_chan);

                    num_feats =  1 + num_rows * num_cols * num_chan;
                end

                if(curr_ind > size(curr_data_buff,1))
                    curr_data_buff = cat(1, curr_data_buff, zeros(6000, num_rows * num_cols * num_chan));
                end
                feature_vec = fread(f, [1, 1 + num_rows * num_cols * num_chan], 'float32');
                curr_data_buff(curr_ind, :) = feature_vec;

            else

                % Reading in batches of 5000

                feature_vec = fread(f, [4 + num_rows * num_cols * num_chan, 5000], 'float32');
                feature_vec = feature_vec(4:end,:)';

                if(~isempty(feature_vec))
                    num_rows_read = size(feature_vec,1);

                    curr_data_buff(curr_ind+1:curr_ind+num_rows_read,:) = feature_vec;
                    %valid_data_buff =
                    curr_ind = curr_ind + size(feature_vec,1);
                end
            end

        end

        fclose(f);

        curr_data_small = curr_data_buff(1:curr_ind,:);
        vid_id_curr = cell(curr_ind,1);
        vid_id_curr(:) = {hog_files(i).name};

        % Keep up to 20 frames from the whole video (so that it is balanced
        % per dataset/video/participant)

        if(nargin > 2)
            num_instances = num_samples;
        else
            num_instances = 20;
        end

        increment = round(curr_ind / num_instances);
        if(increment == 0)
            increment = 1;
        end

        curr_data_small = curr_data_small(1:increment:end,:);
        vid_id_curr = vid_id_curr(1:increment:end,:);

        vid_id = cat(1, vid_id, vid_id_curr);

        % Assume same number of frames per video
        if(i==1)
            hog_data = zeros(10*numel(hog_files), num_feats);
        end

        if(size(hog_data,1) < feats_filled+size(curr_data_small,1))
           hog_data = cat(1, hog_data, zeros(feats_filled + size(curr_data_small,1) - size(hog_data,1), num_feats));
        end

        hog_data(feats_filled+1:feats_filled + size(curr_data_small,1),:) = curr_data_small;

        feats_filled = feats_filled + size(curr_data_small,1);

    end

    valid_inds = hog_data(1:feats_filled,1) > 0;
    hog_data = hog_data(1:feats_filled,2:end);

end


f = findSubjects('/silver/scr1/dti/trilinear_PPD','',{'...','mb041004','nad040610','vt040717','zs040630'});
n = length(f);
for(ii=1:n)
    dt = load(f{ii}, 'anat', 'b0', 'dt6');
    if(ii==1)
        sz = size(dt.anat.img);
        t1_a = zeros([sz(1) sz(2) n]);
        t1_s = zeros([sz(1) sz(3) n]);
        t1_c = zeros([sz(2) sz(3) n]);
        t1Avg = zeros(sz);
        sz = size(dt.b0);
        b0_a = zeros([sz(1) sz(2) n]);
        b0_s = zeros([sz(1) sz(3) n]);
        b0_c = zeros([sz(2) sz(3) n]);
        b0Avg = zeros(sz);
        dt6Avg = zeros(size(dt.dt6));
    end
    t1_a(:,:,ii) = squeeze(dt.anat.img(:,:,91));
    t1_s(:,:,ii) = squeeze(dt.anat.img(:,109,:));
    t1_c(:,:,ii) = squeeze(dt.anat.img(91,:,:));
    t1Avg = t1Avg + dt.anat.img./max(dt.anat.img(:));
    b0_a(:,:,ii) = squeeze(dt.b0(:,:,46));
    b0_s(:,:,ii) = squeeze(dt.b0(:,55,:));
    b0_c(:,:,ii) = squeeze(dt.b0(46,:,:));
    b0Avg = b0Avg + dt.b0./max(dt.b0(:));
    dt6Avg = dt6Avg + dt.dt6;
    %disp(dt.anat.xformToAcPc);
end

figure; imagesc(makeMontage(t1_a)); axis image; colormap gray;
figure; imagesc(makeMontage(t1_s)); axis image; colormap gray;
figure; imagesc(makeMontage(t1_c)); axis image; colormap gray;

figure; imagesc(makeMontage(b0_a)); axis image; colormap gray;
figure; imagesc(makeMontage(b0_s)); axis image; colormap gray;
figure; imagesc(makeMontage(b0_c)); axis image; colormap gray;

figure; imagesc(makeMontage(t1Avg)); axis image; colormap gray;
figure; imagesc(makeMontage(b0Avg)); axis image; colormap gray;
figure; imagesc(makeMontage(permute(t1Avg,[3 1 2]),[29:size(t1Avg,2)-20])); axis image xy; colormap gray;

m = makeMontage(permute(t1Avg,[3 2 1]),[32:size(t1Avg,1)-30]);
figure; imagesc(m); axis image xy; colormap gray;
m = makeMontage(permute(b0Avg,[3 2 1]),[16:size(b0Avg,1)-15]);
figure; imagesc(m); axis image xy; colormap gray;


function spm_eeg_img2maps(S)
% Make a series of scalp maps from data in an image
% FORMAT  spm_eeg_img2maps(S)
%
% S         - input structure (optional)
% (optional) fields of S:
%    D              - M/EEG dataset containing the sensor locations
%    image          - file name of an image containing M/EEG data in voxel-space
%    window         - start and end of a window in peri-stimulus time [ms]
%    clim           - color limits of the plot
%__________________________________________________________________________
% Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging

% Vladimir Litvak
% $Id: spm_eeg_img2maps.m 6669 2016-01-11 15:51:06Z guillaume $

SVNrev = '$Rev: 6669 $';

%-Startup
%--------------------------------------------------------------------------
spm('FnBanner', mfilename, SVNrev);
spm('FigName','Plot scalp maps');

if nargin == 0
    S = [];
end

%% -Input parameters
%--------------------------------------------------------------------------
if ~isfield(S, 'image')
    [S.image, sts] = spm_select(1, 'image', 'Select an M/EEG image (in voxel-space)');
    if ~sts, return; end
end

%-Get MEEG object
%--------------------------------------------------------------------------
try
    D = S.D;
catch
    [D, sts] = spm_select(1, 'mat', 'Select M/EEG mat file');
    if ~sts, D = []; return; end
    S.D = D;
end

D = spm_eeg_load(D);

if ~isfield(S, 'window')
    S.window = spm_input('start and end of window [ms or Hz]', '+1', 'r', '', 2);
end

style = char(spm_input('Plot style','+1','SPM|FT|3D',{'spm','ft','3d'},1));

V = spm_vol(S.image);
Y = spm_read_vols(V);

Nt = size(Y, 3);

begsample = inv(V.mat)*[0 0 S.window(1) 1]';
begsample = begsample(3);

endsample = inv(V.mat)*[0 0 S.window(2) 1]';
endsample = endsample(3);

if any([begsample endsample] < 0) || ...
        any([begsample endsample] > Nt)
    error('The window is out of limits for the image.');
end

[junk begsample] = min(abs(begsample-[1:Nt]));
[junk endsample] = min(abs(endsample-[1:Nt]));

Y = squeeze(mean(Y(: , :, begsample:endsample), 3));

if any(diff(size(Y)))
    error('The image should be square');
else
    n = size(Y, 1);
end

%-Get channel indices and coordinates
%--------------------------------------------------------------------------
modality    = spm_eeg_modality_ui(D, 1, 1);

Cind = D.indchantype(modality, 'GOOD');

Cel = spm_eeg_locate_channels(D, n, Cind);

if isempty(Cind)
    error('No good channels to plot');
end

Y = Y(sub2ind(size(Y), Cel(:, 1), Cel(:, 2)));

%%
% SPM graphics figure
%--------------------------------------------------------------------------
Fgraph  = spm_figure('GetWin','Graphics'); spm_figure('Clear',Fgraph)

switch style
    case 'spm'
        if ~isfield(S, 'clim')
            in.max = max(abs(Y));
            in.min = -in.max;
        else
            in.min = S.clim(1);
            in.max = S.clim(2);
        end

        in.type = modality;
        in.f = Fgraph;
        in.ParentAxes = axes;

        spm_eeg_plotScalpData(Y, D.coor2D(Cind), D.chanlabels(Cind), in);
    case 'ft'

        dummy = [];
        dummy.dimord = 'chan_time';
        dummy.avg = Y;
        dummy.label = D.chanlabels(Cind);
        dummy.time  = 1e-3*mean(S.window);

        cfg = [];
        cfg.parameter = 'avg';
        cfg.comment = 'no';

        switch modality
            case 'EEG'
                cfg.elec = D.sensors('EEG');
            case 'MEG'
                cfg.grad = D.sensors('MEG');
        end
        cfg.zlim = max(abs(Y))*[-1 1];

        ft_topoplotER(cfg, dummy);

    case '3d'
        spm_eeg_headplot(Y, D, axes);
end
%%
%-Cleanup
%--------------------------------------------------------------------------
spm('FigName','Plot scalp maps: done');