Home > functions > internal > dsImportModel.m

dsImportModel

PURPOSE ^

IMPORTMODEL - import model from raw equations, other program source, etc.

SYNOPSIS ^

function [model,map] = dsImportModel(source,varargin)

DESCRIPTION ^

IMPORTMODEL - import model from raw equations, other program source, etc.

 Usage:
   [model,map] = dsImportModel(source,'option',value,...)

 Inputs:
   - source: [string]
     1. file with model equations (DynaSim .mech or .eqns, XPP, ...)
     2. string with equations
     3. reference to DB model with equations
   - options (optional):
     'namespace'      : namespace to prepend to all parameter, variable, and function names
     'ic_pop'         : name of population with state variables defined in this model
         - note: connection mechanisms in target pop can have ic_pop=source
     'host'           : name of database hosting the model to import
     'user_parameters': cell array of key/value pairs to override model parameters

 Output:
   DynaSim model structure (see dsGenerateModel)

 See also: dsGenerateModel, dsCheckModel

 Author: Jason Sherfey, PhD <jssherfey@gmail.com>
 Copyright (C) 2016 Jason Sherfey, Boston University, USA

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function [model,map] = dsImportModel(source,varargin)
0002 %IMPORTMODEL - import model from raw equations, other program source, etc.
0003 %
0004 % Usage:
0005 %   [model,map] = dsImportModel(source,'option',value,...)
0006 %
0007 % Inputs:
0008 %   - source: [string]
0009 %     1. file with model equations (DynaSim .mech or .eqns, XPP, ...)
0010 %     2. string with equations
0011 %     3. reference to DB model with equations
0012 %   - options (optional):
0013 %     'namespace'      : namespace to prepend to all parameter, variable, and function names
0014 %     'ic_pop'         : name of population with state variables defined in this model
0015 %         - note: connection mechanisms in target pop can have ic_pop=source
0016 %     'host'           : name of database hosting the model to import
0017 %     'user_parameters': cell array of key/value pairs to override model parameters
0018 %
0019 % Output:
0020 %   DynaSim model structure (see dsGenerateModel)
0021 %
0022 % See also: dsGenerateModel, dsCheckModel
0023 %
0024 % Author: Jason Sherfey, PhD <jssherfey@gmail.com>
0025 % Copyright (C) 2016 Jason Sherfey, Boston University, USA
0026 
0027 % Check inputs
0028 options=dsCheckOptions(varargin,{...
0029   'host','local',[],... % database, eg: infbrain, modeldb
0030   'namespace',[],[],... % namespace, eg: E, I
0031   'ic_pop',[],[],... % eg: E, I
0032   'user_parameters',[],[],... % eg: {'Cm',1,'gNa',100}
0033   },false);
0034 
0035 % ------------------------------------------------------------------
0036 %% 1.0 Download model if not stored locally
0037 % host:
0038 % check if source string has form HOST:MODEL; update options.host
0039 tmp=regexp(source,':','split');
0040 if numel(tmp)>1
0041   host=tmp{1};
0042   ModelID=str2num(tmp{2});
0043 else
0044   host='local';
0045 end
0046 % download model if source host is known
0047 switch host
0048  case {'infbrain','infinitebrain','ib'}
0049    source=downloadModel(ModelID);
0050 end
0051 
0052 % ------------------------------------------------------------------
0053 %% 2.0 Convert to DynaSim model structure
0054 % if DynaSim .mech, .eqns, .txt:
0055   % parse model equations
0056   [model,map]=dsParseModelEquations(source,'namespace',options.namespace, varargin{:});
0057   
0058 % if DynaSim .mat: load MAT-file
0059 % ... load(source) ...
0060 
0061 % if XPP .ode file: load and convert to DynaSim structure
0062 %  ... xpp2dynasim() ...
0063 
0064 % if NEURON .modl file: ...  neuron2dynasim() ...
0065 
0066 % if NeuroML: ...  neuroml2dynasim() ...
0067 
0068 % if Brian: ...  brian2dynasim() ...
0069 
0070 % ------------------------------------------------------------------
0071 %% 3.0 Post-process model
0072 % override default parameter values by user-supplied values
0073 if ~isempty(options.user_parameters)
0074   model=set_user_parameters(model,options.user_parameters,options.namespace); % set user parameters
0075 end
0076 
0077 % check initial conditions of state variables defined in this (sub-)model
0078 if ~isempty(options.ic_pop)
0079   model=add_missing_ICs(model,options.ic_pop); % add missing ICs
0080 end
0081 
0082 %% 4.0 cleanup
0083 if ~strcmp(host,'local') && exist(source,'file')
0084   delete(source);
0085 end
0086 
0087 % ----------------------------------
0088 function modl=set_user_parameters(modl,params,namespace)
0089   precision=8; % number of digits allowed for user-supplied values
0090   if isempty(params) || isempty(modl.parameters)
0091     return;
0092   end
0093   % prepend namespace to user-supplied params
0094   user_keys=cellfun(@(x)[namespace '_' x],params(1:2:end),'uni',0);
0095   user_vals=params(2:2:end);
0096   
0097   % check for mechanism-specific parameters
0098   if any(~cellfun(@isempty,regexp(user_keys,'\.')))
0099     % at least one key has MECH.PARAM
0100     rem_inds=[]; % inds to user_keys not to be updated in this namespace
0101     key_inds=find(~cellfun(@isempty,regexp(user_keys,'\.'))); % indices into user_keys with .
0102     par_inds=2*key_inds-1; % indices into params for keys with .
0103     % check whether MECH is in this namespace
0104     for i=1:length(key_inds)
0105       % split params key to obtain MECH and PARAM names
0106       o=regexp(params{par_inds(i)},'\.','split');
0107       MECH=o{1};
0108       PARM=o{2};
0109       % check that MECH is in namespace (pat='\_MECH$')
0110       o=regexp(namespace,['\_' MECH '$'],'once');
0111       if ~isempty(o)
0112         % yes: set user_keys{key_inds(i)}=[namespace '_' PARAM]
0113         user_keys{key_inds(i)}=[namespace '_' PARM];
0114       else
0115         % store key_inds(i) to remove from user_keys and user_vals
0116         rem_inds=[rem_inds key_inds(i)];
0117       end
0118     end
0119     % exclude parameters not meant for this namespace
0120     if ~isempty(rem_inds)
0121       user_keys(rem_inds)=[];
0122       user_vals(rem_inds)=[];
0123     end
0124   end
0125   
0126   % HACK
0127   % remove duplicate namespace from user-supplied params
0128 %   for iKey = 1:length(user_keys)
0129 %     locs = regexp(user_keys{iKey}, namespace, 'end');
0130 %     if length(locs) > 1 %then duplicated namespace
0131 %       user_keys{iKey}(1:locs(1)+1) = []; %remove duplicate and trailing _
0132 %     end
0133 %   end
0134   
0135   % get list of parameters in modl
0136   param_names=fieldnames(modl.parameters);
0137   
0138   % find adjusted user-supplied param names in this sub-model
0139   ind=find(ismember(user_keys,param_names));
0140   for p=1:length(ind)
0141     if isnumeric(user_vals{ind(p)}) && size(user_vals{ind(p)},2)>1
0142       modl.parameters.(user_keys{ind(p)})=user_vals{ind(p)};
0143     else
0144       modl.parameters.(user_keys{ind(p)})=toString(user_vals{ind(p)},precision);
0145     end
0146   end
0147   
0148   % repeat for fixed_variables (e.g., connection matrix)
0149   if ~isempty(modl.fixed_variables)
0150     % get list of fixed_variables in modl
0151     fixvars_names=fieldnames(modl.fixed_variables);
0152     
0153     % find adjusted user-supplied param names in this sub-model
0154     ind=find(ismember(user_keys,fixvars_names));
0155     for p=1:length(ind)
0156       if ~ischar(user_vals{ind(p)})
0157         modl.fixed_variables.(user_keys{ind(p)})=toString(user_vals{ind(p)},precision);
0158       else
0159         modl.fixed_variables.(user_keys{ind(p)})=user_vals{ind(p)};
0160       end
0161     end
0162   end
0163 % ----------------------------------
0164 function modl=add_missing_ICs(modl,popname)
0165   if isempty(modl.state_variables)
0166     return;
0167   end
0168   Npopstr=[popname '_Npop'];
0169   % add default ICs if missing (do not evaluate ICs in dsGenerateModel; do that in dsSimulate before saving params.mat)
0170   if isstruct(modl.ICs)
0171     missing_ICs=setdiff(modl.state_variables,fieldnames(modl.ICs));
0172   else
0173     missing_ICs=modl.state_variables;
0174   end
0175   
0176   % add default ICs
0177   for ic=1:length(missing_ICs)
0178     modl.ICs(1).(missing_ICs{ic})=sprintf('zeros(1,%s)',Npopstr);
0179   end
0180   
0181   % convert scalar ICs to vectors of population size
0182   ICfields=fieldnames(modl.ICs);
0183   for ic=1:length(ICfields)
0184     % check if scalar (scientific notation or decimal)
0185     if ~isempty(regexp(modl.ICs.(ICfields{ic}),'^((\d+e[\-\+]?\d+)|([\d.-]+))$','once'))
0186       modl.ICs(1).(ICfields{ic})=sprintf('%s*ones(1,%s)',modl.ICs.(ICfields{ic}),Npopstr);
0187     end
0188   end
0189 
0190 function source=downloadModel(ModelID)
0191 % Set path to your MySQL Connector/J JAR
0192 jarfile = '/usr/share/java/mysql-connector-java.jar';
0193 javaaddpath(jarfile); % WARNING: this might clear global variables
0194 
0195 % set connection parameters
0196 cfg.mysql_connector = 'database';
0197 cfg.webhost = '104.131.218.171'; % 'infinitebrain.org','104.131.218.171'
0198 cfg.dbname = 'modulator';
0199 cfg.dbuser = 'querydb'; % have all users use root to connect to DB and self to transfer files
0200 cfg.dbpassword = 'publicaccess'; % 'publicaccess'
0201 cfg.xfruser = 'publicuser';
0202 cfg.xfrpassword = 'publicaccess';
0203 cfg.ftp_port=21;
0204 cfg.MEDIA_PATH = '/project/infinitebrain/media';
0205 target = pwd; % local directory for temporary files
0206 
0207 % Create the database connection object
0208 jdbcString = sprintf('jdbc:mysql://%s/%s',cfg.webhost,cfg.dbname);
0209 jdbcDriver = 'com.mysql.jdbc.Driver';
0210 dbConn = database(cfg.dbname,cfg.dbuser,cfg.dbpassword,jdbcDriver,jdbcString);
0211 
0212 % list all mechanism metadata from DB
0213 %query='select id,name,level,notes,ispublished,project_id from modeldb_model where level=''mechanism'''; %  and privacy='public'
0214 %data = get(fetch(exec(dbConn,query)), 'Data');
0215 % get file info associated with this ModelID
0216 query=sprintf('select file from modeldb_modelspec where model_id=%g',ModelID);
0217 data = get(fetch(exec(dbConn,query)), 'Data');
0218 jsonfile=data{1};
0219 [usermedia,modelfile,ext] = fileparts2(jsonfile); % remote server media directory
0220 usermedia=fullfile(cfg.MEDIA_PATH,usermedia);
0221 modelfile=[modelfile ext];%'.json'];
0222 
0223 % Open ftp connection and download mechanism file
0224 f=ftp([cfg.webhost ':' num2str(cfg.ftp_port)],cfg.xfruser,cfg.xfrpassword);
0225 pasv(f);
0226 cd(f,usermedia);
0227 mget(f,modelfile,target);
0228 
0229 % parse mechanism file
0230 tempfile = fullfile(target,modelfile);
0231 source=tempfile;
0232 [model,map]=dsParseModelEquations(source, varargin{:});
0233 % if isequal(ext,'.json')
0234 %   [spec,jsonspec] = json2spec(tempfile);
0235 %   spec.model_uid=ModelID;
0236 % elseif isequal(ext,'.txt')
0237 %   spec = parse_mech_spec(tempfile,[]);
0238 % else
0239 %   spec = [];
0240 % end
0241 % delete(tempfile);
0242 %close ftp connection
0243 close(f);

Generated on Tue 12-Dec-2017 11:32:10 by m2html © 2005