Home > atmlab > arts > qarts2cfile.m

qarts2cfile

PURPOSE ^

QARTS2CFILE Builds a control file for ARTS

SYNOPSIS ^

function S = qarts2cfile( Q, parts, workfolder )

DESCRIPTION ^

 QARTS2CFILE   Builds a control file for ARTS

    Creates a control file matching the settings in a Qarts structure.
    The control file is provided as cell array of strings. This means
    that the output can be combined with other control file pieces
    by combining their string arrays. The final control file is
    created by *strs2file*.
    
    The control file structure is determined by putting different 'parts'
    together, following the format: parts = {'Generl','AtmSrfSave'}

    Defined parts are:
       Generl / GenerlSave
       AtmSrf / AtmSrfSave
       Absrpt / AbsrptSave
       CldBox / CldBoxSave
       SctMth / SctMthSave / SctMthBatch
       RteSet
       Sensor / SensorSave 
       Jacobi 
       RteExe
       BatchC

    The later options, including 'Save', adds commands to save main
    variables for the part. These save commands are the only WSM calls that
    are added automaticlly to the control file, everything else must be
    specified by the qarts fields or be handled by include control files.

    For fields that can be given both as a Matlab variable or name of a 
    file, a file is generated automatically if the input a variable.
    Output is stored in files placed in *workfolder*, with names identical
    the WSV name and extension '.xml' (e.g. y.xml).

    The parts to combine for some different tasks can be obtained by 
    this function, using the second format version below. In this case, 
    there shall only be one input argument, and it shall be a plain string.
    Defined options, of general interest, for *runtype* are:
      'GetAtmSrf'  : To obtain variables defining the atmosphere and the 
                     surface.
      'GetAbsTable': To obtain an absorption table.
      'GetSensor'  : To obtain a sensor response matrix.
      'y':         : A complete calcultion, possibly including sensor,
                     scattering and jacobians.
      'y_init':    : Sets up for calculation following the 'y' option, but
                     no radiative transfer calculations performed.
      'batch'      : Batch calculations.

    In most of these cases there is a function to directly perform the
    calculations, named as arts_"runtype", for example arts_y.

 FORMAT   S = qarts2cfile( Q, parts, workfolder )

 OUT   S           String cell array that can be passed to *strs2file*.
 IN    Q           Qarts structure
       parts       Control file parts to include. See further above.
       workfolder  Folder where calculations will be performed. Typically a
                   temporary folder.

             or

 FORMAT   parts = qarts2cfile( runtype )

 OUT   parts     As above
 IN    runtype   String describing type of calculation to perform.
                 See further above.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

DOWNLOAD ^

qarts2cfile.m

SOURCE CODE ^

0001 % QARTS2CFILE   Builds a control file for ARTS
0002 %
0003 %    Creates a control file matching the settings in a Qarts structure.
0004 %    The control file is provided as cell array of strings. This means
0005 %    that the output can be combined with other control file pieces
0006 %    by combining their string arrays. The final control file is
0007 %    created by *strs2file*.
0008 %
0009 %    The control file structure is determined by putting different 'parts'
0010 %    together, following the format: parts = {'Generl','AtmSrfSave'}
0011 %
0012 %    Defined parts are:
0013 %       Generl / GenerlSave
0014 %       AtmSrf / AtmSrfSave
0015 %       Absrpt / AbsrptSave
0016 %       CldBox / CldBoxSave
0017 %       SctMth / SctMthSave / SctMthBatch
0018 %       RteSet
0019 %       Sensor / SensorSave
0020 %       Jacobi
0021 %       RteExe
0022 %       BatchC
0023 %
0024 %    The later options, including 'Save', adds commands to save main
0025 %    variables for the part. These save commands are the only WSM calls that
0026 %    are added automaticlly to the control file, everything else must be
0027 %    specified by the qarts fields or be handled by include control files.
0028 %
0029 %    For fields that can be given both as a Matlab variable or name of a
0030 %    file, a file is generated automatically if the input a variable.
0031 %    Output is stored in files placed in *workfolder*, with names identical
0032 %    the WSV name and extension '.xml' (e.g. y.xml).
0033 %
0034 %    The parts to combine for some different tasks can be obtained by
0035 %    this function, using the second format version below. In this case,
0036 %    there shall only be one input argument, and it shall be a plain string.
0037 %    Defined options, of general interest, for *runtype* are:
0038 %      'GetAtmSrf'  : To obtain variables defining the atmosphere and the
0039 %                     surface.
0040 %      'GetAbsTable': To obtain an absorption table.
0041 %      'GetSensor'  : To obtain a sensor response matrix.
0042 %      'y':         : A complete calcultion, possibly including sensor,
0043 %                     scattering and jacobians.
0044 %      'y_init':    : Sets up for calculation following the 'y' option, but
0045 %                     no radiative transfer calculations performed.
0046 %      'batch'      : Batch calculations.
0047 %
0048 %    In most of these cases there is a function to directly perform the
0049 %    calculations, named as arts_"runtype", for example arts_y.
0050 %
0051 % FORMAT   S = qarts2cfile( Q, parts, workfolder )
0052 %
0053 % OUT   S           String cell array that can be passed to *strs2file*.
0054 % IN    Q           Qarts structure
0055 %       parts       Control file parts to include. See further above.
0056 %       workfolder  Folder where calculations will be performed. Typically a
0057 %                   temporary folder.
0058 %
0059 %             or
0060 %
0061 % FORMAT   parts = qarts2cfile( runtype )
0062 %
0063 % OUT   parts     As above
0064 % IN    runtype   String describing type of calculation to perform.
0065 %                 See further above.
0066 
0067 % 2007-08-21   Large revision of function structure and code. PE
0068 %
0069 % 2004-09-08   Created by Patrick Eriksson (PE).
0070 
0071 
0072 function S = qarts2cfile( Q, parts, workfolder )
0073                                                                             %&%
0074                                                                             %&%
0075 %- Check input                                                              %&%
0076 %                                                                           %&%
0077 if ~( nargin == 1  |  nargin == 3 )                                         %&%
0078   error( 'The function takes 1 or 3 input arguments.' );                    %&%
0079 end                                                                         %&%
0080 
0081 
0082 
0083 %--- Version returning cfile parts --------------------------------------------
0084 %
0085 if nargin == 1
0086                                                                             %&%
0087                                                                             %&%
0088   if ~ischar( Q )                                                           %&%
0089     error( 'If number of arguments is 1, this argument must be a string' ); %&%
0090   end                                                                       %&%
0091 
0092   switch Q
0093 
0094   case 'GetAtmSrf'
0095     %
0096     S = { 'Generl', 'AtmSrfSave', 'CloseF' };
0097 
0098   case 'GetAbsTable'
0099     %
0100     S = { 'Generl', 'AbsrptSave', 'CloseF' };
0101 
0102   case 'GetSensor'
0103     %
0104     S = { 'Generl', 'SensorSave', 'CloseF' };
0105    
0106   case 'y_init'
0107     %
0108     S = { 'Generl', 'AtmSrf', 'Absrpt', 'RteSet', 'SensorSave', ...
0109           'JacobiSave', 'CloseF' };
0110     
0111   case 'y_after_init'
0112     %
0113     S = { 'Generl', 'AtmSrf', 'Absrpt', 'RteSet', 'Sensor', 'Jacobi', ...
0114           'CldBox', 'SctMth', 'RteExe', 'CloseF' };
0115    
0116   case 'y'
0117     %
0118     S = { 'Generl', 'AtmSrf', 'Absrpt', 'RteSet', 'Sensor', 'JacobiSave', ...
0119           'CldBox', 'SctMth', 'RteExe', 'CloseF' };
0120 
0121   case 'Batch'
0122     %
0123     S = { 'Generl', 'AtmSrf', 'Absrpt', 'RteSet', 'Sensor', 'Jacobi', ...
0124           'CldBox', 'SctMthBatch', 'BatchC', 'CloseF' };
0125                                                                             %&%
0126   otherwise                                                                 %&%
0127     error( sprintf( 'Unknown cfile type (%s) was requested.', Q ) );        %&%
0128   end
0129 
0130   return    % --->
0131 end
0132 %------------------------------------------------------------------------------
0133 
0134 
0135 
0136 %--- Version returning string struture ----------------------------------------
0137 
0138 if atmlab( 'STRICT_ASSERT' )
0139   qcheck( @qarts, Q );
0140 end
0141 
0142 S    = {};
0143 
0144 for ip = 1 : length(parts)
0145 
0146   T = [];
0147 
0148   switch parts{ip}(1:6)
0149     
0150    case 'Generl'
0151     %
0152     T = cfile_Generl( Q, parts{ip}, workfolder );
0153 
0154    case 'CloseF'
0155     %
0156     T = cfile_CloseF( Q, parts{ip}, workfolder );
0157     
0158    case 'AtmSrf'
0159     %
0160     T = cfile_AtmSrf( Q, parts{ip}, workfolder );
0161    
0162    case 'Absrpt'
0163     %
0164     T = cfile_Absrpt( Q, parts{ip}, workfolder );
0165    
0166    case 'RteSet'
0167     %
0168     T = cfile_RteSet( Q, parts{ip}, workfolder );
0169    
0170    case 'Sensor'
0171     %
0172     T = cfile_Sensor( Q, parts{ip}, workfolder );
0173     
0174    case 'Jacobi'
0175     %
0176     T = cfile_Jacobi( Q, parts{ip}, workfolder );
0177    
0178    case 'CldBox'
0179     %
0180     T = cfile_CldBox( Q, parts{ip}, workfolder );
0181    
0182    case 'SctMth'
0183     %
0184     T = cfile_SctMth( Q, parts{ip}, workfolder );
0185    
0186    case 'RteExe'
0187     %
0188     T = cfile_RteExe( Q, parts{ip}, workfolder );
0189 
0190    case 'BatchC'
0191     %
0192     T = cfile_BatchC( Q, parts{ip}, workfolder );
0193     
0194    otherwise
0195     error( sprintf( 'Unknown cfile part (%s) was requested.', parts{ip} ) );
0196   end
0197   
0198   if ~isempty(T)
0199    S = { S{:} T{:} };
0200   end
0201 
0202 end
0203 
0204 return
0205 %------------------------------------------------------------------------------
0206 %--- End main
0207 %------------------------------------------------------------------------------
0208 
0209 
0210 
0211 %------------------------------------------------------------------------------
0212 %--- Sub-functions for main control file parts
0213 %------------------------------------------------------------------------------
0214 
0215 %------------------------------------------------------------------------------
0216 % Sub-function handling:
0217 %
0218 %    Start of cfile
0219 %    output_file_format
0220 %    stokes_dim
0221 %    f_grid
0222 %    abs_species
0223 %
0224 function T = cfile_Generl( Q, partname, workfolder )
0225   %                                                                         %&%
0226   if ~( strcmp( partname, 'Generl' )  |  strcmp( partname, 'GenerlSave' ) ) %&%
0227     error( 'Only recognised choices are ''Generl'' and ''GenerlSave''.' );  %&%
0228   end                                                                       %&%
0229   %
0230   T{1} = [ '# Control file created by Atmlab function *qarts2cfile*' ];
0231   T{2} = 'Arts2{';
0232   %
0233   T = add_includes( T, 'Q.INCLUDES', Q.INCLUDES );
0234   %
0235   if qarts_isset( Q.WSMS_AT_START )
0236     T = add_wsms( T, ' WSMS_AT_START', Q.WSMS_AT_START, Q );
0237   end
0238   %
0239   if qarts_isset( Q.OUTPUT_FILE_FORMAT )
0240     rqre_datatype( Q.OUTPUT_FILE_FORMAT, @ischar, 'Q.OUTPUT_FILE_FORMAT' ); %&%
0241     if ~any( strcmp( lower(Q.OUTPUT_FILE_FORMAT), {'binary','ascii'} ) )    %&%
0242       error( 'Q.OUTPUT_FILE_FORMAT must be ''binary'' or ''ascii''.' );     %&%
0243     end                                                                     %&%
0244     T{end+1} = sprintf( 'output_file_formatSet%s%s', ...
0245       upper(Q.OUTPUT_FILE_FORMAT(1)), lower(Q.OUTPUT_FILE_FORMAT(2:end)) );
0246   end
0247   %
0248   rqre_datatype( Q.INPUT_FILE_FORMAT, @ischar, 'Q.INPUT_FILE_FORMAT' );     %&%
0249   if ~any( strcmp( lower(Q.INPUT_FILE_FORMAT), {'binary','double'} ) )      %&%
0250     error( 'Q.INPUT_FILE_FORMAT must be ''binary'' or ''double''.' );       %&%
0251   end                                                                       %&%
0252   %
0253   if qarts_isset( Q.STOKES_DIM )
0254     rqre_alltypes( Q.STOKES_DIM, {@istensor0,@iswhole}, 'Q.STOKES_DIM' );   %&%
0255     rqre_in_range( Q.STOKES_DIM, 1, 4, 'Q.STOKES_DIM' );                    %&%
0256     T{end+1} = sprintf( 'IndexSet(stokes_dim,%d)', Q.STOKES_DIM );
0257   end
0258   %
0259   if qarts_isset( Q.F_GRID )
0260     T = file_or_data( T, 'f_grid', 'Vector', Q.F_GRID, workfolder, ...
0261                                                      Q.INPUT_FILE_FORMAT );
0262   end
0263   %
0264   if qarts_isset( Q.ATMOSPHERE_DIM )
0265     rqre_alltypes( Q.ATMOSPHERE_DIM, {@istensor0,@iswhole}, ...             %&%
0266                                                       'Q.ATMOSPHERE_DIM' ); %&%
0267     rqre_in_range( Q.ATMOSPHERE_DIM, 1, 3, 'Q.ATMOSPHERE_DIM' );            %&%
0268     T{end+1} = sprintf( 'AtmosphereSet%dD', Q.ATMOSPHERE_DIM );
0269   end
0270   %
0271   if qarts_isset( Q.ABS_SPECIES )
0272     rqre_datatype( Q.ABS_SPECIES, @isstruct, 'Q.ABS_SPECIES' );             %&%
0273     rqre_field( Q.ABS_SPECIES, 'TAG', 'Q.ABS_SPECIES' );                    %&%
0274     T{end+1} = sprintf( 'abs_speciesSet(species=[%s])', ...
0275                                            arts_tgs_cnvrt(Q.ABS_SPECIES) );
0276   end
0277   %
0278   if strcmp( partname, 'GenerlSave' )
0279     T{end+1} = add_savefile( 'output_file_format', workfolder );
0280     T{end+1} = add_savefile( 'stokes_dim', workfolder );
0281     T{end+1} = add_savefile( 'f_grid', workfolder );
0282     T{end+1} = add_savefile( 'abs_species', workfolder );
0283   end  
0284 return
0285 
0286 
0287 
0288 %------------------------------------------------------------------------------
0289 % Sub-function handling:
0290 %
0291 %    Closing of cfile
0292 %    WSMS_AT_END
0293 %
0294 function T = cfile_CloseF( Q, partname, workfolder )
0295   %
0296   T = [];
0297   %
0298   if qarts_isset( Q.WSMS_AT_END )
0299     T = add_wsms( T, ' WSMS_AT_END', Q.WSMS_AT_END, Q );
0300   end
0301   %
0302   T{end+1} = '}';
0303 return
0304 
0305 
0306 
0307 %------------------------------------------------------------------------------
0308 % Sub-function handling:
0309 %
0310 %    atmosphere_dim
0311 %    p_grid
0312 %    lat_grid
0313 %    lon_grid
0314 %    t_field
0315 %    z_field
0316 %    vmr_field
0317 %    refellipsoid
0318 %    z_surface
0319 %    winds
0320 %
0321 function T = cfile_AtmSrf( Q, partname, workfolder )
0322   %                                                                         %&%
0323   if ~( strcmp( partname, 'AtmSrf' )  |  strcmp( partname, 'AtmSrfSave' ) ) %&%
0324     error( 'Only recognised choices are ''AtmSrf'' and ''AtmSrfSave''.' );  %&%
0325   end                                                                       %&%
0326   %
0327   T = [];
0328   %
0329   if qarts_isset( Q.WSMS_BEFORE_ATMSURF )
0330     T = add_wsms( T, 'Q.WSMS_BEFORE_ATMSURF', Q.WSMS_BEFORE_ATMSURF, Q );
0331   end
0332   %
0333   if qarts_isset( Q.P_GRID )
0334     T = file_or_data( T, 'p_grid', 'Vector', Q.P_GRID, workfolder, ...
0335                                                      Q.INPUT_FILE_FORMAT );
0336   end
0337   %
0338   if qarts_isset( Q.LAT_GRID ) 
0339     T = file_or_data( T, 'lat_grid', 'Vector', Q.LAT_GRID, workfolder, ...
0340                                                          Q.INPUT_FILE_FORMAT );
0341   end
0342   if qarts_isset( Q.LON_GRID ) 
0343     T = file_or_data( T, 'lon_grid', 'Vector', Q.LON_GRID, workfolder, ...
0344                                                          Q.INPUT_FILE_FORMAT );
0345   end
0346   %
0347   if qarts_isset( Q.LAT_TRUE ) 
0348     T = file_or_data( T, 'lat_true', 'Vector', Q.LAT_TRUE, workfolder, ...
0349                                                          Q.INPUT_FILE_FORMAT );
0350   end
0351   if qarts_isset( Q.LON_TRUE ) 
0352     T = file_or_data( T, 'lon_true', 'Vector', Q.LON_TRUE, workfolder, ...
0353                                                          Q.INPUT_FILE_FORMAT );
0354   end
0355   %
0356   if qarts_isset( Q.RAW_ATMOSPHERE )
0357     rqre_datatype( Q.RAW_ATMOSPHERE, @ischar, 'Q.RAW_ATMOSPHERE' );         %&%
0358     if qarts_isset( Q.RAW_ATM_EXPAND_1D )                                   %&%
0359       rqre_datatype( Q.RAW_ATM_EXPAND_1D, @isboolean, ...                   %&%
0360                                                    'Q.RAW_ATM_EXPAND_1D' ); %&%
0361     end                                                                     %&%
0362     T{end+1} = sprintf( 'AtmRawRead(basename="%s")', Q.RAW_ATMOSPHERE );
0363     if qarts_isset( Q.RAW_ATM_EXPAND_1D ) & Q.RAW_ATM_EXPAND_1D
0364       wsm = 'AtmFieldsCalcExpand1D';
0365     else
0366       wsm = 'AtmFieldsCalc';
0367     end
0368     T{end+1} = sprintf( '%s(vmr_zeropadding=%d)', wsm, 0 );
0369   end
0370   %
0371   if qarts_isset( Q.T_FIELD )
0372     T = file_or_data( T, 't_field', 'Tensor3', Q.T_FIELD, ...
0373                                              workfolder, Q.INPUT_FILE_FORMAT );
0374   end      
0375   if qarts_isset( Q.VMR_FIELD )
0376     T = file_or_data( T, 'vmr_field', 'Tensor4', Q.VMR_FIELD, ...
0377                                              workfolder, Q.INPUT_FILE_FORMAT );
0378   end      
0379   if qarts_isset( Q.Z_FIELD )
0380     T = file_or_data( T, 'z_field', 'Tensor3', Q.Z_FIELD, ...
0381                                              workfolder, Q.INPUT_FILE_FORMAT );
0382   end
0383   %
0384   if qarts_isset( Q.WIND_U_FIELD )
0385     T = file_or_data( T, 'wind_u_field', 'Tensor3', Q.WIND_U_FIELD, ...
0386                                              workfolder, Q.INPUT_FILE_FORMAT );
0387   end      
0388   if qarts_isset( Q.WIND_V_FIELD )
0389     T = file_or_data( T, 'wind_v_field', 'Tensor3', Q.WIND_V_FIELD, ...
0390                                              workfolder, Q.INPUT_FILE_FORMAT );
0391   end      
0392   if qarts_isset( Q.WIND_W_FIELD )
0393     T = file_or_data( T, 'wind_w_field', 'Tensor3', Q.WIND_W_FIELD, ...
0394                                              workfolder, Q.INPUT_FILE_FORMAT );
0395   end
0396   %
0397   if qarts_isset( Q.MAG_U_FIELD )
0398     T = file_or_data( T, 'mag_u_field', 'Tensor3', Q.MAG_U_FIELD, ...
0399                                              workfolder, Q.INPUT_FILE_FORMAT );
0400   end      
0401   if qarts_isset( Q.MAG_V_FIELD )
0402     T = file_or_data( T, 'mag_v_field', 'Tensor3', Q.MAG_V_FIELD, ...
0403                                              workfolder, Q.INPUT_FILE_FORMAT );
0404   end      
0405   if qarts_isset( Q.MAG_W_FIELD )
0406     T = file_or_data( T, 'mag_w_field', 'Tensor3', Q.MAG_W_FIELD, ...
0407                                              workfolder, Q.INPUT_FILE_FORMAT );
0408   end
0409   %
0410   if qarts_isset(Q.REFELLIPSOID)
0411     rqre_datatype( Q.REFELLIPSOID, {@istensor1}, 'Q.REFELLIPSOID' );        %&%
0412     T = file_or_data( T, 'refellipsoid', 'Vector', Q.REFELLIPSOID, ...
0413                                          workfolder, Q.INPUT_FILE_FORMAT );
0414   end
0415   %
0416   if qarts_isset(Q.Z_SURFACE)
0417     T = file_or_data( T, 'z_surface', 'Matrix', Q.Z_SURFACE, ...
0418                                          workfolder, Q.INPUT_FILE_FORMAT );
0419   end
0420   %
0421   if qarts_isset(Q.VMR_NEGATIVE_OK) & Q.VMR_NEGATIVE_OK 
0422     T{end+1} = 'atmfields_checkedCalc(negative_vmr_ok=1)';
0423   else
0424     T{end+1} = 'atmfields_checkedCalc';
0425   end
0426   T{end+1} = 'atmgeom_checkedCalc';
0427   %
0428   if qarts_isset( Q.HSE )
0429     if ~isfield( Q.HSE, 'ON' ) & ~isbool( Q.HSE.ON )                        %&%
0430       error( ...                                                            %&%
0431       'When Q.HSE is present, HSE.ON must be a present and be a boolean.'); %&%
0432     end                                                                     %&%
0433     if Q.HSE.ON
0434       if ~isfield( Q.HSE, {'P','ACCURACY'} )                                %&%
0435         error( 'With Q.HSE.ON true the fields P and ACCURACY must exist' ); %&%
0436       end                                                                   %&%
0437       rqre_datatype( Q.HSE.P, @istensor0, 'Q.HSE.P' );                      %&%
0438       rqre_datatype( Q.HSE.ACCURACY, @istensor0, 'Q.HSE.ACCURACY' );        %&%
0439       T{end+1} = sprintf( 'NumericSet(p_hse,%.3f)', Q.HSE.P );      
0440       T{end+1} = sprintf( 'NumericSet(z_hse_accuracy,%.3f)', Q.HSE.ACCURACY );
0441       T{end+1} = 'z_fieldFromHSE';
0442     else
0443       % To allow dummy values for t retrievals without HSE
0444       if isfield( Q.HSE, 'P' ) 
0445         T{end+1} = sprintf( 'NumericSet(p_hse,%.3f)', Q.HSE.P );      
0446       end
0447       if isfield( Q.HSE, 'ACCURACY' ) 
0448         T{end+1} = sprintf( 'NumericSet(z_hse_accuracy,%.3f)', Q.HSE.ACCURACY );
0449       end
0450     end
0451   end
0452   %
0453   if strcmp( partname, 'AtmSrfSave' )
0454     T{end+1} = add_savefile( 'atmosphere_dim', workfolder );
0455     T{end+1} = add_savefile( 'p_grid', workfolder );
0456     T{end+1} = add_savefile( 'lat_grid', workfolder );
0457     T{end+1} = add_savefile( 'lon_grid', workfolder );
0458     T{end+1} = add_savefile( 't_field', workfolder );
0459     T{end+1} = add_savefile( 'z_field', workfolder );
0460     T{end+1} = add_savefile( 'vmr_field', workfolder );
0461     T{end+1} = add_savefile( 'refellipsoid', workfolder );
0462     T{end+1} = add_savefile( 'z_surface', workfolder );
0463   end
0464   
0465 return
0466 
0467 
0468 
0469 %------------------------------------------------------------------------------
0470 % Sub-function handling:
0471 %
0472 %    basic absorption variables, such as abs_lines (if used)
0473 %    abs_lookup  (if used)
0474 %    propmat_clearsky_agenda
0475 %    abs_xsec_agenda
0476 %
0477 function T = cfile_Absrpt( Q, partname, workfolder )
0478   %
0479   abstable = false;
0480   %
0481   T = {};
0482   %                                                                         %&%
0483   if ~( strcmp( partname, 'Absrpt' )  |  strcmp( partname, 'AbsrptSave' ) ) %&%
0484     error( 'Only recognised choices are ''Absrpt'' and ''AbsrptSave''.' );  %&%
0485   end                                                                       %&%
0486   %
0487   if qarts_isset( Q.ABSORPTION )
0488     rqre_datatype( Q.ABSORPTION, @ischar, 'Q.ABSORPTION' );                 %&%
0489     %                                                                       %&%
0490     if ~( strcmp(Q.ABSORPTION,'OnTheFly') | ...                             %&%
0491           strcmp(Q.ABSORPTION,'LoadTable') | ...                            %&%
0492           strcmp(Q.ABSORPTION,'CalcTable') )                                %&%
0493       error( ['Only recognised choices for *ABSORPTION* are ',...           %&%
0494                        '''OnTheFly'', ''LoadTable'' and ''CalcTable''.'] ); %&%
0495     end                                                                     %&%
0496     %
0497     if strcmp(Q.ABSORPTION,'OnTheFly') | strcmp(Q.ABSORPTION, 'CalcTable')
0498       %
0499       nset = qarts_isset( Q.ABS_LINESHAPE )  +  ...
0500              qarts_isset( Q.ABS_LINESHAPE_FACTOR ) + ...
0501              qarts_isset( Q.ABS_LINESHAPE_CUTOFF );
0502       %
0503       if nset  
0504         if nset < 3
0505           error( ['Q.ABS_LINESHAPE, Q.ABS_LINESHAPE_FACTOR, and ', ...
0506          'Q.ABS_LINESHAPE_CUTOFF must all be left empty ({}), or all be set.']);
0507         end
0508         %                                                                   %&%
0509         rqre_datatype( Q.ABS_LINESHAPE, @ischar, 'Q.ABS_LINESHAPE' );       %&%
0510         rqre_datatype( Q.ABS_LINESHAPE_FACTOR, @ischar, ...                 %&%
0511                                                 'Q.ABS_LINESHAPE_FACTOR' ); %&%
0512         rqre_datatype( Q.ABS_LINESHAPE_CUTOFF, @istensor0, ...              %&%
0513                                                 'Q.ABS_LINESHAPE_CUTOFF' ); %&%
0514         T{end+1} = sprintf('abs_lineshapeDefine(abs_lineshape,"%s","%s",%e)',...
0515              Q.ABS_LINESHAPE, Q.ABS_LINESHAPE_FACTOR, Q.ABS_LINESHAPE_CUTOFF );
0516       end
0517       %
0518       if qarts_isset( Q.ABS_LINES_FORMAT )
0519         %                                                                   %&%
0520         rqre_datatype( Q.ABS_LINES_FORMAT, @ischar, 'Q.ABS_LINES_FORMAT' ); %&%
0521         %
0522         if strcmp( upper(Q.ABS_LINES_FORMAT), 'NONE' )
0523           T{end+1} = 'abs_lines_per_speciesSetEmpty';
0524         else
0525           %
0526           rqre_datatype( Q.ABS_LINES, {@ischar,@isstruct,@isempty}, ...     %&%
0527                                                            'Q.ABS_LINES' ); %&%
0528           %
0529           if strcmp(upper(Q.ABS_LINES_FORMAT),'ARTS') & ~ischar(Q.ABS_LINES)
0530             filename = fullfile( workfolder, 'abs_lines.xml' );
0531             T = file_or_data( T, 'abs_lines', 'ArrayOfLineRecord', ...
0532                             Q.ABS_LINES, workfolder, Q.INPUT_FILE_FORMAT );
0533           else
0534             if ~ischar( Q.ABS_LINES )                                       %&%
0535               error( ...                                                    %&%
0536                'Q.ABS_LINES must be a filename for formats beside Arts.' ); %&%
0537             end                                                             %&%
0538             filename = Q.ABS_LINES;
0539           end
0540           %
0541           T{end+1} = sprintf( 'abs_linesReadFrom%s(abs_lines,"%s",0,1e99)', ...
0542                                                 Q.ABS_LINES_FORMAT, filename );
0543           T{end+1} = 'abs_lines_per_speciesCreateFromLines';
0544         end
0545       end
0546       %
0547       T = add_includes( T, 'Q.ABS_MODELS', Q.ABS_MODELS );
0548       %
0549       if qarts_isset( Q.ABS_WSMS )
0550         T = add_wsms( T, 'ABS_WSMS', Q.ABS_WSMS, Q );
0551       end
0552     end
0553         
0554     if qarts_isset( Q.ABS_XSEC_AGENDA )
0555       T = add_agenda( T, 'abs_xsec_agenda', Q.ABS_XSEC_AGENDA );
0556     else      
0557       T = add_agenda( T, 'abs_xsec_agenda', { ...
0558                          'abs_xsec_per_speciesInit', ...
0559                          'abs_xsec_per_speciesAddLines', ...
0560                          'abs_xsec_per_speciesAddConts' } );
0561     end
0562     T{end+1} = 'abs_xsec_agenda_checkedCalc';
0563 
0564     if strcmp( Q.ABSORPTION, 'OnTheFly' )
0565       %
0566       if qarts_isset( Q.PROPMAT_CLEARSKY_AGENDA )
0567         T = add_agenda( T, 'propmat_clearsky_agenda', ...
0568                                                 Q.PROPMAT_CLEARSKY_AGENDA );
0569       else      
0570         T = add_agenda( T, 'propmat_clearsky_agenda', { ...
0571                   'Ignore(rtp_mag)', 'Ignore(rtp_los)', ...
0572                   'propmat_clearskyInit', 'propmat_clearskyAddOnTheFly' } );
0573       end
0574       %
0575     elseif strcmp( Q.ABSORPTION, 'CalcTable' )
0576       %
0577       if qarts_isset( Q.ABS_P )
0578         T = file_or_data( T, 'abs_p', 'Vector', Q.ABS_P, ...
0579                                          workfolder, Q.INPUT_FILE_FORMAT );
0580       end
0581       if qarts_isset( Q.ABS_T )
0582         T = file_or_data( T, 'abs_t', 'Vector', Q.ABS_T, ...
0583                                          workfolder, Q.INPUT_FILE_FORMAT );
0584       end
0585       if qarts_isset( Q.ABS_T_PERT )
0586         T = file_or_data( T, 'abs_t_pert', 'Vector', Q.ABS_T_PERT, ...
0587                                          workfolder, Q.INPUT_FILE_FORMAT );
0588       end
0589       if qarts_isset( Q.ABS_VMRS )
0590         T = file_or_data( T, 'abs_vmrs', 'Matrix', Q.ABS_VMRS, ...
0591                                          workfolder, Q.INPUT_FILE_FORMAT );
0592       end
0593       if qarts_isset( Q.ABS_NLS )
0594         rqre_datatype( Q.ABS_NLS, {@isempty,@iscellstr}, 'Q.ABS_NLS' );     %&%
0595         if isempty( Q.ABS_NLS )
0596           T{end+1} = 'abs_speciesSet(abs_species=abs_nls,species=[])';
0597         else
0598           T{end+1} = sprintf( ...
0599               'abs_speciesSet(abs_species=abs_nls,species=[%s])', ...
0600                                                    arts_tgs_cnvrt(Q.ABS_NLS) );
0601         end
0602         % As abs_species changed, this must be repeated:
0603         T{end+1} = 'abs_xsec_agenda_checkedCalc'; 
0604       end
0605       if qarts_isset( Q.ABS_NLS_PERT )
0606         T = file_or_data( T, 'abs_nls_pert', 'Vector', Q.ABS_NLS_PERT, ...
0607                                          workfolder, Q.INPUT_FILE_FORMAT );
0608       end
0609       %
0610       T{end+1} = 'abs_lookupCalc'; 
0611       if qarts_isset( Q.PROPMAT_CLEARSKY_AGENDA )
0612         T = add_agenda( T, 'propmat_clearsky_agenda', ...
0613                                                 Q.PROPMAT_CLEARSKY_AGENDA );
0614       else      
0615         T = add_agenda( T, 'propmat_clearsky_agenda', { ...
0616             'Ignore(rtp_mag)', 'Ignore(rtp_los)', ...
0617             'propmat_clearskyInit', 'propmat_clearskyAddFromLookup' } );
0618       end 
0619       %
0620       abstable = true;
0621       %
0622     elseif strcmp( Q.ABSORPTION, 'LoadTable' )
0623       %
0624       T = file_or_data( T, 'abs_lookup', 'GasAbsLookup', Q.ABS_LOOKUP, ...
0625                                          workfolder, Q.INPUT_FILE_FORMAT );
0626       T{end+1} = 'abs_lookupAdapt';
0627       if qarts_isset( Q.PROPMAT_CLEARSKY_AGENDA )
0628         T = add_agenda( T, 'propmat_clearsky_agenda', ...
0629                                                 Q.PROPMAT_CLEARSKY_AGENDA );
0630       else      
0631         T = add_agenda( T, 'propmat_clearsky_agenda', { ...
0632                 'Ignore(rtp_mag)', 'Ignore(rtp_los)',...
0633                 'propmat_clearskyInit', 'propmat_clearskyAddFromLookup' } );
0634       end
0635       %
0636       abstable = true;
0637       %
0638     end
0639     
0640     T{end+1} = 'propmat_clearsky_agenda_checkedCalc';
0641     
0642   end %  qarts_isset( Q.ABSORPTION )
0643 
0644   
0645   if abstable  &  strcmp( partname, 'AbsrptSave' )
0646     T{end+1} = add_savefile( 'abs_lookup', workfolder );
0647   end
0648 return
0649 
0650 
0651 
0652 %------------------------------------------------------------------------------
0653 % Sub-function handling:
0654 %
0655 %    blackbody_radiation_agenda
0656 %    surface_rtprop_agenda
0657 %    iy_surface_agenda
0658 %    iy_space_agenda
0659 %    iy_transmitter_agenda
0660 %    ppath_lmax
0661 %    ppath_lraytrace
0662 %    ppath_step_agenda
0663 %    refr_index_air__agenda
0664 %    rte_agenda
0665 %    sensor_pos
0666 %    sensor_los
0667 %    sensor_time
0668 %    transmitter_pos
0669 %
0670 function T = cfile_RteSet( Q, partname, workfolder )
0671   %                                                                         %&%
0672   if ~strcmp( partname, 'RteSet' )                                          %&%
0673     error( 'Only recognised choices is ''RteSet''.' );                      %&%
0674   end                                                                       %&%
0675   %
0676   T = {};
0677   %
0678   if qarts_isset( Q.BLACKBODY_RADIATION_AGENDA )
0679     T = add_agenda( T, 'blackbody_radiation_agenda', ...
0680                                                 Q.BLACKBODY_RADIATION_AGENDA );
0681   end    
0682   if qarts_isset( Q.SURFACE_RTPROP_AGENDA )
0683     T = add_agenda( T, 'surface_rtprop_agenda', Q.SURFACE_RTPROP_AGENDA );
0684   end
0685   if qarts_isset( Q.IY_SURFACE_AGENDA )
0686     T = add_agenda( T, 'iy_surface_agenda', Q.IY_SURFACE_AGENDA );
0687   end
0688   if qarts_isset( Q.IY_SPACE_AGENDA )
0689     T = add_agenda( T, 'iy_space_agenda', Q.IY_SPACE_AGENDA );
0690   end
0691   if qarts_isset( Q.IY_TRANSMITTER_AGENDA )
0692     T = add_agenda( T, 'iy_transmitter_agenda', Q.IY_TRANSMITTER_AGENDA );
0693   end
0694   if qarts_isset( Q.PPATH_LMAX )
0695     rqre_datatype( Q.PPATH_LMAX, @istensor0, 'Q.PPATH_LMAX' );              %&%
0696     T{end+1} = sprintf( 'NumericSet( ppath_lmax, %.2e )', Q.PPATH_LMAX );
0697   end  
0698   if qarts_isset( Q.PPATH_LRAYTRACE )
0699     rqre_datatype( Q.PPATH_LRAYTRACE, @istensor0, 'Q.PPATH_LRAYTRACE' );    %&%
0700     T{end+1} = sprintf( 'NumericSet( ppath_lraytrace, %.2e )', ...
0701                                                        Q.PPATH_LRAYTRACE );
0702   end  
0703   if qarts_isset( Q.PPATH_AGENDA )
0704     T = add_agenda( T, 'ppath_agenda', Q.PPATH_AGENDA );
0705   end
0706   if qarts_isset( Q.PPATH_STEP_AGENDA )
0707     T = add_agenda( T, 'ppath_step_agenda', Q.PPATH_STEP_AGENDA );
0708   end
0709   if qarts_isset( Q.REFR_INDEX_AIR_AGENDA )
0710     T = add_agenda( T, 'refr_index_air_agenda', Q.REFR_INDEX_AIR_AGENDA );
0711   end
0712   if qarts_isset( Q.SENSOR_POS )
0713     T = file_or_data( T, 'sensor_pos', 'Matrix', Q.SENSOR_POS,...
0714                                           workfolder, Q.INPUT_FILE_FORMAT );
0715   end
0716   if qarts_isset( Q.SENSOR_LOS )
0717     T = file_or_data( T, 'sensor_los', 'Matrix', Q.SENSOR_LOS,...
0718                                           workfolder, Q.INPUT_FILE_FORMAT );
0719   end
0720   if qarts_isset( Q.SENSOR_TIME )
0721     T = file_or_data( T, 'sensor_time', 'Vector', Q.SENSOR_TIME,...
0722                                           workfolder, Q.INPUT_FILE_FORMAT );
0723   end
0724   if qarts_isset( Q.TRANSMITTER_POS )
0725     T = file_or_data( T, 'transmitter_pos', 'Matrix', Q.TRANSMITTER_POS,...
0726                                           workfolder, Q.INPUT_FILE_FORMAT );
0727   end
0728   if qarts_isset( Q.IY_MAIN_AGENDA )
0729     T = add_agenda( T, 'iy_main_agenda', Q.IY_MAIN_AGENDA );
0730   end
0731   if qarts_isset( Q.IY_SUB_AGENDA )
0732     T = add_agenda( T, 'iy_sub_agenda', Q.IY_SUB_AGENDA );
0733   end
0734   if qarts_isset( Q.IY_AUX_VARS )
0735     T = file_or_data( T, 'iy_aux_vars', 'ArrayOfString', Q.IY_AUX_VARS,...
0736                                           workfolder, Q.INPUT_FILE_FORMAT );
0737   end
0738   if qarts_isset( Q.IY_UNIT )
0739     rqre_datatype( Q.IY_UNIT, @ischar, 'Q.IY_UNIT' );                       %&%
0740     T{end+1} = sprintf( 'StringSet(iy_unit,"%s")', Q.IY_UNIT );
0741   end
0742   %
0743   T{end+1} = add_savefile( 'sensor_pos', workfolder );
0744   T{end+1} = add_savefile( 'sensor_los', workfolder );
0745   %
0746 return
0747 
0748 
0749 
0750 % Sub-function handling:
0751 %
0752 %    y and associated variables
0753 %    jacobian
0754 %
0755 function T = cfile_RteExe( Q, partname, workfolder )
0756   %                                                                         %&%
0757   if ~strcmp( partname, 'RteExe' )                                          %&%
0758     error( 'Only recognised choice is ''RteExe''.' );                       %&%
0759   end                                                                       %&%
0760   %
0761   T = add_rtecalcstart( Q );
0762   %
0763   T{end+1} = 'sensor_checkedCalc';
0764   %
0765   if qarts_isset( Q.YCALC_WSMS )
0766     T = add_wsms( T, 'YCALC_WSMS', Q.YCALC_WSMS, Q );
0767   end
0768   %
0769   T{end+1} = add_savefile( 'y',       workfolder );
0770 %  T{end+1} = add_savefile( 'y_f',     workfolder );
0771 %  T{end+1} = add_savefile( 'y_pol',   workfolder );
0772 %  T{end+1} = add_savefile( 'y_pos',   workfolder );
0773 %  T{end+1} = add_savefile( 'y_los',   workfolder );
0774   T{end+1} = add_savefile( 'y_aux',   workfolder );
0775   %
0776   if qarts_isset( Q.J_DO ) 
0777     rqre_datatype( Q.J_DO, @isboolean, 'Q.J_DO' );                          %&%
0778     if Q.J_DO
0779       T{end+1} = add_savefile( 'jacobian', workfolder );
0780     end
0781   end
0782 return
0783 
0784 
0785 
0786 % Sub-function handling:
0787 %
0788 %    sensor variables
0789 %
0790 function T = cfile_Sensor( Q, partname, workfolder )
0791   %                                                                         %&%
0792   if ~( strcmp( partname, 'Sensor' )  |  strcmp( partname, 'SensorSave' ) ) %&%
0793     error( 'Only recognised choices are ''Sensor'' and ''SensorSave''.' );  %&%
0794   end                                                                       %&%
0795 
0796   do_parts = false;
0797 
0798   if ~qarts_isset( Q.SENSOR_DO )
0799     T = {};
0800     return                           % Return
0801   end
0802     
0803   rqre_datatype( Q.SENSOR_DO, @isboolean, 'Q.SENSOR_DO' );                  %&%
0804   if ~Q.SENSOR_DO
0805     T{1} = 'sensorOff';
0806     return                           % Return
0807   end
0808     
0809   rqre_datatype( Q.SENSOR_RESPONSE, ...                                     %&%
0810            {@ischar,@issparse,@iscellstr,@isstruct}, 'Q.SENSOR_RESPONSE' ); %&%
0811 
0812   do_parts = 0;
0813   %
0814   if isstruct( Q.SENSOR_RESPONSE )
0815     do_parts = 1;
0816   elseif ischar(Q.SENSOR_RESPONSE)  |  issparse(Q.SENSOR_RESPONSE)
0817     T = file_or_data( {}, 'sensor_response', 'Sparse', Q.SENSOR_RESPONSE, ...
0818                                          workfolder, Q.INPUT_FILE_FORMAT );
0819     if qarts_isset( Q.ANTENNA_DIM )
0820       T = file_or_data( T, 'antenna_dim', 'Index', Q.ANTENNA_DIM, ...
0821                                          workfolder, Q.INPUT_FILE_FORMAT );
0822     end
0823     if qarts_isset( Q.MBLOCK_ZA_GRID )
0824       T = file_or_data( T, 'mblock_za_grid', 'Vector', Q.MBLOCK_ZA_GRID,...
0825                                          workfolder, Q.INPUT_FILE_FORMAT );
0826     end
0827     if qarts_isset( Q.MBLOCK_AA_GRID )
0828       T = file_or_data( T, 'mblock_aa_grid', 'Vector', Q.MBLOCK_AA_GRID,...
0829                                          workfolder, Q.INPUT_FILE_FORMAT );
0830     end
0831     if qarts_isset( Q.SENSOR_RESPONSE_F )
0832       T = file_or_data( T, 'sensor_response_f', 'Vector', ...
0833                     Q.SENSOR_RESPONSE_F, workfolder, Q.INPUT_FILE_FORMAT );
0834     end
0835     if qarts_isset( Q.SENSOR_RESPONSE_ZA )
0836       T = file_or_data( T, 'sensor_response_za', 'Vector', ...
0837                    Q.SENSOR_RESPONSE_ZA, workfolder, Q.INPUT_FILE_FORMAT );
0838     end
0839     if qarts_isset( Q.SENSOR_RESPONSE_AA )
0840       T = file_or_data( T, 'sensor_response_aa', 'Vector', ...
0841                    Q.SENSOR_RESPONSE_AA, workfolder, Q.INPUT_FILE_FORMAT );
0842     end
0843     if qarts_isset( Q.SENSOR_RESPONSE_POL )
0844       T = file_or_data( T, 'sensor_response_pol', 'ArrayOfIndex', ...
0845                   Q.SENSOR_RESPONSE_POL, workfolder, Q.INPUT_FILE_FORMAT );
0846     end
0847     if qarts_isset( Q.SENSOR_RESPONSE_F_GRID )
0848       T = file_or_data( T, 'sensor_response_f_grid', 'Vector', ...
0849                Q.SENSOR_RESPONSE_F_GRID, workfolder, Q.INPUT_FILE_FORMAT );
0850     end
0851     if qarts_isset( Q.SENSOR_RESPONSE_ZA_GRID )
0852       T = file_or_data( T, 'sensor_response_za_grid', 'Vector', ...
0853               Q.SENSOR_RESPONSE_ZA_GRID, workfolder, Q.INPUT_FILE_FORMAT );
0854     end
0855     if qarts_isset( Q.SENSOR_RESPONSE_AA_GRID )
0856       T = file_or_data( T, 'sensor_response_aa_grid', 'Vector', ...
0857               Q.SENSOR_RESPONSE_AA_GRID, workfolder, Q.INPUT_FILE_FORMAT );
0858     end
0859     if qarts_isset( Q.SENSOR_RESPONSE_POL_GRID )
0860       T = file_or_data( T, 'sensor_response_pol_grid', 'ArrayOfIndex', ...
0861              Q.SENSOR_RESPONSE_POL_GRID, workfolder, Q.INPUT_FILE_FORMAT );
0862     end
0863   elseif iscellstr( Q.SENSOR_RESPONSE ) 
0864     T = Q.SENSOR_RESPONSE;
0865   end
0866 
0867   %- Structure version:
0868   %
0869   if do_parts  
0870     %
0871     H = Q.SENSOR_RESPONSE;
0872     %
0873     qcheck( @qartsSensor, H );
0874 
0875     % Find out sensor structure
0876     parts{1} = 'init';
0877     if qarts_isset( H.SENSOR_POL )
0878       parts{end+1} = 'polarisation';
0879     end
0880     if qarts_isset( H.ANTENNA_DO ) & H.ANTENNA_DO
0881       parts{end+1} = 'antenna';
0882     end
0883     if qarts_isset( H.FILL_FGRID )
0884       parts{end+1} = 'fill_fgrid';
0885     end
0886     if qarts_isset( H.MIXER_DO ) & H.MIXER_DO 
0887       parts{end+1} = 'mixer';
0888     end
0889     if qarts_isset( H.IF2RF ) & H.IF2RF 
0890       parts{end+1} = 'if2rf';
0891     end
0892     if qarts_isset( H.BACKEND_DO ) & H.BACKEND_DO
0893       parts{end+1} = 'backend';
0894     end
0895     if qarts_isset( H.BEAM_SWITCHING )  &  H.BEAM_SWITCHING
0896       parts{end+1} = 'beamswitch';
0897     end
0898     % If multiple LO are given exchange 'mixer' for 'multimixer' and 'remove
0899     % 'backend'
0900     if( any(strcmp( 'mixer', parts ))   &  ...
0901         any(strcmp( 'backend', parts )) &  length(H.LO) > 1 )
0902       %
0903       ir        = find( strcmp('mixer',parts) );
0904       parts{ir} = 'multimixer';
0905       parts     = parts{ find( ~strcmp('backend',parts) ) };
0906     end
0907     parts{end+1} = 'close';
0908         
0909     % Start writing to output structure
0910     T = {};
0911 
0912     for it = 1 : length(parts)
0913       %
0914       U = {};
0915 
0916       switch parts{it}
0917 
0918       case 'init'
0919         U{1} = ['# Start of sensor part:'];
0920         if qarts_isset( H.ANTENNA_DO )  &  ~H.ANTENNA_DO
0921           U{end+1} = 'AntennaOff';
0922         end
0923         if qarts_isset( Q.ANTENNA_DIM ) 
0924           rqre_alltypes( Q.ANTENNA_DIM, {@istensor0,@iswhole}, ...          %&%
0925                                                           'Q.STOKES_DIM' ); %&%
0926           rqre_in_range( Q.ANTENNA_DIM, 1, 2, 'Q.ANTENNA_DIM' );            %&%
0927           U{end+1} = sprintf( 'AntennaSet%dD', Q.ANTENNA_DIM );
0928         end
0929         if qarts_isset( Q.MBLOCK_ZA_GRID ) 
0930           U = file_or_data( U, 'mblock_za_grid', 'Vector', ...
0931                        Q.MBLOCK_ZA_GRID, workfolder, Q.INPUT_FILE_FORMAT );
0932         end        
0933         if qarts_isset( Q.MBLOCK_AA_GRID ) 
0934           U = file_or_data( U, 'mblock_aa_grid', 'Vector', ...
0935                        Q.MBLOCK_AA_GRID, workfolder, Q.INPUT_FILE_FORMAT );
0936         end
0937         if qarts_isset( H.SENSOR_NORM )
0938           rqre_datatype( H.SENSOR_NORM, @isboolean, ...                     %&%
0939                                          'Q.SENSOR_RESPONSE.SENSOR_NORM' ); %&%
0940           U{end+1} = sprintf( 'IndexSet(sensor_norm,%d)', H.SENSOR_NORM );
0941         end
0942         U{end+1} = 'sensor_responseInit';
0943         
0944       case 'fill_fgrid'
0945         v = qarts_get( H.FILL_FGRID );
0946         if ~( isnumeric(v) & isvector(v) & length(v) == 2 )                 %&%
0947           error( 'The sensor *FILL_FGRID* must be a vector of length 2.' ); %&%
0948         end                                                                 %&%
0949         U{end+1} = sprintf( ...
0950            'sensor_responseFillFgrid(polyorder=%d,nfill=%d)', v(1), v(2) );
0951        
0952       case 'polarisation'
0953         if qarts_isset( H.SENSOR_POL )
0954           U = file_or_data( U, 'sensor_pol', 'ArrayOfIndex', ...
0955                                H.SENSOR_POL, workfolder, Q.INPUT_FILE_FORMAT );
0956         end
0957         U{end+1} = 'sensor_responsePolarisation';
0958        
0959        case 'antenna'
0960         if qarts_isset( H.ANTENNA_LOS )
0961           U = file_or_data( U, 'antenna_los', 'Matrix', H.ANTENNA_LOS, ...
0962                                         workfolder, Q.INPUT_FILE_FORMAT );
0963         end
0964         if qarts_isset( H.ANTENNA_RESPONSE )
0965           U = file_or_data( U, 'antenna_response', 'GriddedField4',...
0966                     H.ANTENNA_RESPONSE, workfolder, Q.INPUT_FILE_FORMAT );
0967         end
0968         U{end+1} = 'sensor_responseAntenna';
0969         
0970       case 'mixer'
0971         if qarts_isset( H.LO ) 
0972           U = file_or_data( U, 'lo', 'Numeric', H.LO, ...
0973                                         workfolder, Q.INPUT_FILE_FORMAT );
0974         end
0975         if qarts_isset( H.SIDEBAND_RESPONSE )           
0976           U = file_or_data( U, 'sideband_response', 'GriddedField1', ...
0977                    H.SIDEBAND_RESPONSE, workfolder, Q.INPUT_FILE_FORMAT );
0978         end
0979         if qarts_isset( H.SIDEBAND_MODE )           
0980           U = file_or_data( U, 'sideband_mode', 'String', ...
0981                    H.SIDEBAND_MODE, workfolder, Q.INPUT_FILE_FORMAT );
0982         end
0983         U{end+1} = 'sensor_responseMixer';
0984 
0985       case 'if2rf'
0986         U{end+1} = 'sensor_responseIF2RF';
0987         
0988       case 'backend'
0989         if qarts_isset( H.F_BACKEND ) 
0990           U = file_or_data( U, 'f_backend', 'Vector', H.F_BACKEND, ...
0991                                         workfolder, Q.INPUT_FILE_FORMAT );
0992         end        
0993         if qarts_isset( H.BACKEND_CHANNEL_RESPONSE )
0994           U = file_or_data( U, 'backend_channel_response', ...
0995             'ArrayOfGriddedField1', H.BACKEND_CHANNEL_RESPONSE, ...
0996                                         workfolder, Q.INPUT_FILE_FORMAT );
0997         end
0998         if ~qarts_isset( H.F_SWITCHING )
0999           U{end+1} = 'sensor_responseBackend';
1000         else
1001           df = qarts_get( H.F_SWITCHING );
1002           if ~( isnumeric(df) & isvector(df) & length(df)==2 )              %&%
1003           error( 'The sensor *F_SWITCHING* must be a vector of length 2.' );%&%
1004           end                                                               %&%
1005           U{end+1} = 'sensor_responseBackendFrequencySwitching(';
1006           U{end+1} = sprintf( '   df1=%.6e, df2=%.6e)', df(1), df(2) );
1007         end
1008         
1009        case 'multimixer'
1010         if qarts_isset( H.F_SWITCHING )
1011           error( 'The sensor *F_SWITCHING* option can not be used together ',...
1012                                                          'with multiple LO.' );
1013         end
1014         if qarts_isset( H.LO ) 
1015           U = file_or_data( U, 'lo_multi', 'Vector', H.LO, workfolder, ...
1016                                                      Q.INPUT_FILE_FORMAT );
1017         end
1018         if qarts_isset( H.SIDEBAND_RESPONSE )           
1019           U = file_or_data( U, 'sideband_response_multi', ...
1020                      'ArrayOfGriddedField1', H.SIDEBAND_RESPONSE, ...
1021                                          workfolder, Q.INPUT_FILE_FORMAT );
1022         end   
1023         if qarts_isset( H.SIDEBAND_MODE )           
1024           U = file_or_data( U, 'sideband_mode_multi', 'ArrayOfString', ...
1025                             H.SIDEBAND_MODE, workfolder, Q.INPUT_FILE_FORMAT );
1026         end   
1027         if qarts_isset( H.F_BACKEND ) 
1028           U = file_or_data( U, 'f_backend_multi', 'ArrayOfVector', ...
1029                             H.F_BACKEND, workfolder, Q.INPUT_FILE_FORMAT );
1030         end        
1031         if qarts_isset( H.BACKEND_CHANNEL_RESPONSE )
1032           U = file_or_data( U, 'backend_channel_response_multi', ....
1033                  'ArrayOfArrayOfGriddedField1', H.BACKEND_CHANNEL_RESPONSE, ... 
1034                                          workfolder, Q.INPUT_FILE_FORMAT );
1035         end
1036         U{end+1} = 'sensor_responseMultiMixerBackend';
1037         
1038       case 'beamswitch'
1039         U{1} = 'sensor_responseBeamSwitching';
1040         
1041       case 'close'
1042         U{1} = '# End of sensor part';
1043 
1044       otherwise
1045         error(sprintf('Unknown action (%s) was requested.',parts{it}));
1046       end
1047 
1048       T = { T{:} U{:} };
1049     end
1050   end
1051   
1052   %- Saving
1053   %
1054   if strcmp( partname, 'SensorSave' )
1055     T{end+1} = add_savefile( 'sensor_response',          workfolder );
1056     T{end+1} = add_savefile( 'sensor_response_f',        workfolder );
1057     T{end+1} = add_savefile( 'sensor_response_za',       workfolder );
1058     T{end+1} = add_savefile( 'sensor_response_aa',       workfolder );
1059     T{end+1} = add_savefile( 'sensor_response_pol',      workfolder );
1060     T{end+1} = add_savefile( 'sensor_response_f_grid',   workfolder );
1061     T{end+1} = add_savefile( 'sensor_response_za_grid',  workfolder );
1062     T{end+1} = add_savefile( 'sensor_response_aa_grid',  workfolder );
1063     T{end+1} = add_savefile( 'sensor_response_pol_grid', workfolder );
1064     T{end+1} = add_savefile( 'antenna_dim',              workfolder );
1065     T{end+1} = add_savefile( 'mblock_za_grid',           workfolder );
1066     T{end+1} = add_savefile( 'mblock_aa_grid',           workfolder );
1067   end
1068 
1069 return
1070 
1071 
1072 
1073 %------------------------------------------------------------------------------
1074 % Sub-function handling:
1075 %
1076 %    jacobians
1077 %
1078 function T = cfile_Jacobi( Q, partname, workfolder )
1079   %
1080   if ~( strcmp( partname, 'Jacobi' ) |  strcmp( partname, 'JacobiSave' ) )
1081     error( 'Only recognised choices are ''Jacobi'' and ''JacobiSave''.' );
1082   end
1083 
1084   do_parts = false;
1085   
1086   if ~qarts_isset( Q.J_DO )
1087      T={};
1088      return
1089   elseif ~Q.J_DO
1090     T{1} = 'jacobianOff';
1091     return
1092   end
1093 
1094 
1095   T{1} = 'jacobianInit';
1096 
1097   %- Gas species
1098   %                                                                         %&%
1099   rqre_field( Q.ABS_SPECIES, 'RETRIEVE', 'Q.ABS_SPECIES' );                 %&%
1100   %
1101   if any( [ Q.ABS_SPECIES.RETRIEVE ] == true )      
1102     %                                                                       %&%
1103     if ~isfield( Q.ABS_SPECIES, {'UNIT','GRIDS'} )                          %&%
1104       error( ['With Q.ABS_SPECIES.RETRIEVED true the fields ', ...          %&%
1105               '''UNIT'' and ''GRIDS'' must exist.'] );                      %&%
1106     end                                                                     %&%
1107     %
1108     for i = 1 : length(Q.ABS_SPECIES)
1109       %
1110       rqre_datatype( Q.ABS_SPECIES(i).RETRIEVE, @isboolean, ...             %&%
1111                                  sprintf('Q.ABS_SPECIES(%d).RETRIEVE',i) ); %&%
1112       %
1113       if Q.ABS_SPECIES(i).RETRIEVE
1114         %
1115         rqre_datatype( Q.ABS_SPECIES(i).UNIT, @ischar, ...                  %&%
1116                                      sprintf('Q.ABS_SPECIES(%d).UNIT',i) ); %&%
1117         rqre_datatype( Q.ABS_SPECIES(i).GRIDS, @iscell, ...                 %&%
1118                                     sprintf('Q.ABS_SPECIES(%d).GRIDS',i) ); %&%
1119         if length(Q.ABS_SPECIES(i).GRIDS) ~= 3                              %&%
1120               error( 'Q.ABS_SPECIES(%d).GRIDS has not length 3.', i );      %&%
1121         end                                                                 %&%
1122         %
1123         name1    = sprintf( 'gas%d_jac_p_grid', i );
1124         T{end+1} = create_var( name1, 'Vector' );
1125         T = file_or_data( T, name1, 'Vector', Q.ABS_SPECIES(i).GRIDS{1},...
1126                                   workfolder, Q.INPUT_FILE_FORMAT, name1 );
1127         name2 = sprintf( 'gas%d_jac_lat_grid', i );
1128         T{end+1} = create_var( name2, 'Vector' );
1129         T = file_or_data( T, name2, 'Vector', Q.ABS_SPECIES(i).GRIDS{2},...
1130                                   workfolder, Q.INPUT_FILE_FORMAT, name2 );
1131         name3 = sprintf( 'gas%d_jac_lon_grid', i );
1132         T{end+1} = create_var( name3, 'Vector' );
1133         T = file_or_data( T, name3, 'Vector', Q.ABS_SPECIES(i).GRIDS{3},...
1134                                   workfolder, Q.INPUT_FILE_FORMAT, name3 );
1135 
1136         T{end+1} ='jacobianAddAbsSpecies(jacobian_quantities,jacobian_agenda,';
1137         T{end+1} = '   atmosphere_dim,p_grid,lat_grid,lon_grid,';
1138         T{end+1} = sprintf( '  %s,%s,%s,', name1, name2, name3 );
1139         T{end+1} = sprintf( '  %s,', arts_tgs_cnvrt(Q.ABS_SPECIES(i).TAG) );
1140         T{end+1} = sprintf( '  "analytical","%s",0.0)', Q.ABS_SPECIES(i).UNIT);
1141       end
1142     end % for
1143   end % if
1144 
1145   
1146   %- Atmospheric temperatures
1147   %                                                                         %&%
1148   if qarts_isset( Q.T )
1149     if ~isfield( Q.T, 'RETRIEVE' )                                          %&%
1150        error( 'When Q.T exists, the field RETRIEVE must be set.' );         %&%
1151     end                                                                     %&%
1152     rqre_datatype( Q.T.RETRIEVE, @isboolean, 'Q.T.RETRIEVE' );              %&%
1153     if Q.T.RETRIEVE
1154       %                                                                     %&%
1155       if ~isfield( Q.T, {'GRIDS'} )                                         %&%
1156         error( 'With Q.T.RETRIEVED true the field ''GRIDS'' must exist.' ); %&%
1157       end                                                                   %&%
1158       rqre_datatype( Q.T.GRIDS, @iscell, 'Q.T.GRIDS' );                     %&%
1159       if length(Q.T.GRIDS) ~= 3                                             %&%
1160         error( 'Q.T.GRIDS has not length 3.' );                             %&%
1161       end                                                                   %&%
1162       %
1163       name1    = 'temperature_jac_p_grid';
1164       T{end+1} = create_var( name1, 'Vector' );
1165       T        = file_or_data( T, name1, 'Vector', Q.T.GRIDS{1}, ...
1166                                 workfolder, Q.INPUT_FILE_FORMAT, name1 );
1167       name2    = 'temperature_jac_lat_grid';
1168       T{end+1} = create_var( name2, 'Vector' );
1169       T        = file_or_data( T, name2, 'Vector', Q.T.GRIDS{2}, ...
1170                                 workfolder, Q.INPUT_FILE_FORMAT, name2 );
1171       name3    = 'temperature_jac_lon_grid';
1172       T{end+1} = create_var( name3, 'Vector' );
1173       T        = file_or_data( T, name3, 'Vector', Q.T.GRIDS{3},...
1174                                     workfolder, Q.INPUT_FILE_FORMAT, name3 );
1175       hse = 'on'; method = 'analytical'; dt = 1;
1176       if isfield( Q.T, 'HSE' ) & qarts_isset( Q.T.HSE ), hse = Q.T.HSE; end
1177       if isfield( Q.T, 'METHOD' ) & qarts_isset( Q.T.METHOD ), 
1178         method = Q.T.METHOD; 
1179       end
1180       if isfield( Q.T, 'DT' ) & qarts_isset( Q.T.DT ), dt = Q.T.DT; end      
1181       T{end+1} ='jacobianAddTemperature(jacobian_quantities,jacobian_agenda,';
1182       T{end+1} = '   atmosphere_dim,p_grid,lat_grid,lon_grid,';
1183       T{end+1} = sprintf( '  %s,%s,%s,', name1, name2, name3 );
1184       T{end+1} = sprintf( '  "%s","%s",%.3f)', hse, method, dt );
1185     end  
1186   end
1187 
1188   %- Wind, U
1189   %                                                                         %&%
1190   if qarts_isset( Q.WIND_U )
1191     if ~isfield( Q.WIND_U, 'RETRIEVE' )                                     %&%
1192        error( 'When Q.WIND_U exists, the field RETRIEVE must be set.' );    %&%
1193     end                                                                     %&%
1194     rqre_datatype( Q.WIND_U.RETRIEVE, @isboolean, 'Q.WIND_U.RETRIEVE' );    %&%
1195     if Q.WIND_U.RETRIEVE                                                    
1196       %                                                                     %&%
1197       if ~isfield( Q.WIND_U, {'GRIDS'} )                                    %&%
1198         error( ...                                                          %&%
1199           'With Q.WIND_U.RETRIEVED true the field ''GRIDS'' must exist.' ); %&%
1200       end                                                                   %&%
1201       rqre_datatype( Q.WIND_U.GRIDS, @iscell, 'Q.WIND_U.GRIDS' );           %&%
1202       if length(Q.WIND_U.GRIDS) ~= 3                                        %&%
1203         error( 'Q.WIND_U.GRIDS has not length 3.' );                        %&%
1204       end                                                                   %&%
1205       %
1206       name1    = 'wind_u_jac_p_grid';
1207       T{end+1} = create_var( name1, 'Vector' );
1208       T        = file_or_data( T, name1, 'Vector', Q.WIND_U.GRIDS{1}, ...
1209                                 workfolder, Q.INPUT_FILE_FORMAT, name1 );
1210       name2    = 'wind_u_jac_lat_grid';
1211       T{end+1} = create_var( name2, 'Vector' );
1212       T        = file_or_data( T, name2, 'Vector', Q.WIND_U.GRIDS{2}, ...
1213                                 workfolder, Q.INPUT_FILE_FORMAT, name2 );
1214       name3    = 'wind_u_jac_lon_grid';
1215       T{end+1} = create_var( name3, 'Vector' );
1216       T        = file_or_data( T, name3, 'Vector', Q.WIND_U.GRIDS{3},...
1217                                     workfolder, Q.INPUT_FILE_FORMAT, name3 );
1218       T{end+1} ='jacobianAddWind(jacobian_quantities,jacobian_agenda,';
1219       T{end+1} = '   atmosphere_dim,p_grid,lat_grid,lon_grid,';
1220       T{end+1} = sprintf( '  %s,%s,%s,"u")', name1, name2, name3 );
1221     end  
1222   end  
1223 
1224   %- Wind, V
1225   %                                                                         %&%
1226   if qarts_isset( Q.WIND_V )
1227     if ~isfield( Q.WIND_V, 'RETRIEVE' )                                     %&%
1228        error( 'When Q.WIND_V exists, the field RETRIEVE must be set.' );    %&%
1229     end                                                                     %&%
1230     rqre_datatype( Q.WIND_V.RETRIEVE, @isboolean, 'Q.WIND_V.RETRIEVE' );    %&%
1231     if Q.WIND_V.RETRIEVE                                                    
1232       %                                                                     %&%
1233       if ~isfield( Q.WIND_V, {'GRIDS'} )                                    %&%
1234         error( ...                                                          %&%
1235           'With Q.WIND_V.RETRIEVED true the field ''GRIDS'' must exist.' ); %&%
1236       end                                                                   %&%
1237       rqre_datatype( Q.WIND_V.GRIDS, @iscell, 'Q.WIND_V.GRIDS' );           %&%
1238       if length(Q.WIND_V.GRIDS) ~= 3                                        %&%
1239         error( 'Q.WIND_V.GRIDS has not length 3.' );                        %&%
1240       end                                                                   %&%
1241       %
1242       name1    = 'wind_v_jac_p_grid';
1243       T{end+1} = create_var( name1, 'Vector' );
1244       T        = file_or_data( T, name1, 'Vector', Q.WIND_V.GRIDS{1}, ...
1245                                 workfolder, Q.INPUT_FILE_FORMAT, name1 );
1246       name2    = 'wind_v_jac_lat_grid';
1247       T{end+1} = create_var( name2, 'Vector' );
1248       T        = file_or_data( T, name2, 'Vector', Q.WIND_V.GRIDS{2}, ...
1249                                 workfolder, Q.INPUT_FILE_FORMAT, name2 );
1250       name3    = 'wind_v_jac_lon_grid';
1251       T{end+1} = create_var( name3, 'Vector' );
1252       T        = file_or_data( T, name3, 'Vector', Q.WIND_V.GRIDS{3},...
1253                                     workfolder, Q.INPUT_FILE_FORMAT, name3 );
1254       T{end+1} ='jacobianAddWind(jacobian_quantities,jacobian_agenda,';
1255       T{end+1} = '   atmosphere_dim,p_grid,lat_grid,lon_grid,';
1256       T{end+1} = sprintf( '  %s,%s,%s,"v")', name1, name2, name3 );
1257     end  
1258   end  
1259   
1260   %- Wind, W
1261   %                                                                         %&%
1262   if qarts_isset( Q.WIND_W )
1263     if ~isfield( Q.WIND_W, 'RETRIEVE' )                                     %&%
1264        error( 'When Q.WIND_W exists, the field RETRIEVE must be set.' );    %&%
1265     end                                                                     %&%
1266     rqre_datatype( Q.WIND_W.RETRIEVE, @isboolean, 'Q.WIND_W.RETRIEVE' );    %&%
1267     if Q.WIND_W.RETRIEVE                                                    
1268       %                                                                     %&%
1269       if ~isfield( Q.WIND_W, {'GRIDS'} )                                    %&%
1270         error( ...                                                          %&%
1271           'With Q.WIND_W.RETRIEVED true the field ''GRIDS'' must exist.' ); %&%
1272       end                                                                   %&%
1273       rqre_datatype( Q.WIND_W.GRIDS, @iscell, 'Q.WIND_W.GRIDS' );           %&%
1274       if length(Q.WIND_W.GRIDS) ~= 3                                        %&%
1275         error( 'Q.WIND_W.GRIDS has not length 3.' );                        %&%
1276       end                                                                   %&%
1277       %
1278       name1    = 'wind_w_jac_p_grid';
1279       T{end+1} = create_var( name1, 'Vector' );
1280       T        = file_or_data( T, name1, 'Vector', Q.WIND_W.GRIDS{1}, ...
1281                                 workfolder, Q.INPUT_FILE_FORMAT, name1 );
1282       name2    = 'wind_w_jac_lat_grid';
1283       T{end+1} = create_var( name2, 'Vector' );
1284       T        = file_or_data( T, name2, 'Vector', Q.WIND_W.GRIDS{2}, ...
1285                                 workfolder, Q.INPUT_FILE_FORMAT, name2 );
1286       name3    = 'wind_w_jac_lon_grid';
1287       T{end+1} = create_var( name3, 'Vector' );
1288       T        = file_or_data( T, name3, 'Vector', Q.WIND_W.GRIDS{3},...
1289                                     workfolder, Q.INPUT_FILE_FORMAT, name3 );
1290       T{end+1} ='jacobianAddWind(jacobian_quantities,jacobian_agenda,';
1291       T{end+1} = '   atmosphere_dim,p_grid,lat_grid,lon_grid,';
1292       T{end+1} = sprintf( '  %s,%s,%s,"w")', name1, name2, name3 );
1293     end  
1294   end  
1295   
1296   %- Frequency
1297   %
1298   if qarts_isset(Q.FSHIFTFIT) 
1299     rqre_datatype( Q.FSHIFTFIT, @isstruct, 'Q.FSHIFTFIT' );                 %&%
1300     rqre_field( Q.FSHIFTFIT, 'RETRIEVE', 'Q.FSHIFTFIT' );                   %&%
1301     rqre_datatype( Q.FSHIFTFIT.RETRIEVE, @isboolean, ...                    %&%
1302                                                  'Q.FSHIFTFIT.RETRIEVAL' ); %&%
1303     if Q.FSHIFTFIT.RETRIEVE
1304       rqre_field( Q.FSHIFTFIT, 'DF', 'Q.FSHIFTFIT' );                       %&%
1305       rqre_datatype( Q.FSHIFTFIT.DF, @istensor0, 'Q.FSHIFTFIT.DF' );        %&%
1306       T{end+1} = 'jacobianAddFreqShift(jacobian_quantities,jacobian_agenda,';
1307       T{end+1} = sprintf('   f_grid,sensor_pos,sensor_time,0,%f)', ...
1308                                                             Q.FSHIFTFIT.DF );
1309     end
1310   end
1311   if qarts_isset(Q.FSTRETCHFIT) 
1312     rqre_datatype( Q.FSTRETCHFIT, @isstruct, 'Q.FSTRETCHFIT' );             %&%
1313     rqre_field( Q.FSTRETCHFIT, 'RETRIEVE', 'Q.FSTRETCHFIT' );               %&%
1314     rqre_datatype( Q.FSTRETCHFIT.RETRIEVE, @isboolean, ...                  %&%
1315                                                'Q.FSTRETCHFIT.RETRIEVAL' ); %&%
1316     if Q.FSTRETCHFIT.RETRIEVE
1317       rqre_field( Q.FSTRETCHFIT, 'DF', 'Q.FSTRETCHFIT' );                   %&%
1318       rqre_datatype( Q.FSTRETCHFIT.DF, @istensor0, 'Q.FSTRETCHFIT.DF' );    %&%
1319       T{end+1} = 'jacobianAddFreqStretch(jacobian_quantities,jacobian_agenda,';
1320       T{end+1} = sprintf('   f_grid,sensor_pos,sensor_time,0,%f)', ...
1321                                                           Q.FSTRETCHFIT.DF );
1322     end
1323   end
1324 
1325   %- Pointing
1326   %
1327   if qarts_isset(Q.POINTING) 
1328     rqre_datatype( Q.POINTING, @isstruct, 'Q.POINTING' );                   %&%
1329     rqre_field( Q.POINTING, 'RETRIEVE', 'Q.POINTING' );                     %&%
1330     rqre_datatype( Q.POINTING.RETRIEVE, @isboolean, ...                     %&%
1331                                                   'Q.POINTING.RETRIEVAL' ); %&%
1332     if Q.POINTING.RETRIEVE
1333       rqre_field( Q.POINTING, 'DZA', 'Q.POINTING' );                        %&%
1334       rqre_datatype( Q.POINTING.DZA, @istensor0, 'Q.POINTING.DZA' );        %&%
1335       rqre_field( Q.POINTING, 'POLY_ORDER', 'Q.POINTING' );                 %&%
1336       rqre_alltypes( Q.POINTING.POLY_ORDER, {@istensor0,@iswhole}, ...      %&%
1337                                                  'Q.POINTING.POLY_ORDER' ); %&%
1338       rqre_field( Q.POINTING, 'CALCMODE', 'Q.POINTING' );                   %&%
1339       rqre_datatype( Q.POINTING.CALCMODE, @ischar, Q.POINTING.CALCMODE' );  %&%
1340       T{end+1} = 'jacobianAddPointingZa(jacobian_quantities, jacobian_agenda,';
1341       T{end+1} =  '   sensor_pos, sensor_time,';
1342       T{end+1} = sprintf( '   %d,"%s",%d)', Q.POINTING.POLY_ORDER, ...
1343                                          Q.POINTING.CALCMODE, Q.POINTING.DZA );
1344     end
1345   end
1346 
1347   %- Polyfit
1348   %
1349   if qarts_isset(Q.POLYFIT) 
1350     rqre_datatype( Q.POLYFIT, @isstruct, 'Q.POLYFIT' );                     %&%
1351     rqre_field( Q.POLYFIT, 'RETRIEVE', 'Q.POLYFIT' );                       %&%
1352     rqre_datatype( Q.POLYFIT.RETRIEVE, @isboolean, 'Q.POLYFIT.RETRIEVAL' ); %&%
1353     if Q.POLYFIT.RETRIEVE
1354       rqre_field( Q.POLYFIT, 'ORDER', 'Q.POLYFIT' );                        %&%
1355       rqre_alltypes( Q.POLYFIT.ORDER, {@istensor0,@iswhole}, ...            %&%
1356                                                        'Q.POLYFIT.ORDER' ); %&%
1357       T{end+1} = 'jacobianAddPolyfit(jacobian_quantities, jacobian_agenda,';
1358       T{end+1} =  '   sensor_response_pol_grid,sensor_response_za_grid,';
1359       T{end+1} = sprintf( '   sensor_pos,%d)', Q.POLYFIT.ORDER );
1360     end
1361   end
1362   
1363   %- Sinefit
1364   %
1365   if qarts_isset(Q.SINEFIT) 
1366     rqre_datatype( Q.SINEFIT, @isstruct, 'Q.SINEFIT' );                     %&%
1367     rqre_field( Q.SINEFIT, 'RETRIEVE', 'Q.SINEFIT' );                       %&%
1368     rqre_datatype( Q.SINEFIT.RETRIEVE, @isboolean, 'Q.SINEFIT.RETRIEVAL' ); %&%
1369     if Q.SINEFIT.RETRIEVE
1370       rqre_field( Q.SINEFIT, 'PERIODS', 'Q.SINEFIT' );                      %&%
1371       rqre_datatype( Q.SINEFIT.PERIODS, @istensor1, 'Q.SINEFIT.PERIODS' );  %&%
1372       T{end+1} = 'jacobianAddSinefit(jacobian_quantities, jacobian_agenda,';
1373       T{end+1} =  '   sensor_response_pol_grid,sensor_response_za_grid,';
1374       s = sprintf( '   sensor_pos,[%f', Q.SINEFIT.PERIODS(1) );
1375       for i = 2:length(Q.SINEFIT.PERIODS)
1376         s = sprintf( '%s,%f', s, Q.SINEFIT.PERIODS(i) );
1377       end
1378       s = [ s, '])' ];
1379       T{end+1} = s;
1380     end
1381   end
1382   
1383   T{end+1} = 'jacobianClose';    
1384 
1385   
1386   %- Saving
1387   %
1388   if strcmp( partname, 'JacobiSave' )
1389     T{end+1} = add_savefile( 'jacobian_quantities', workfolder );
1390     T{end+1} = add_savefile( 'jacobian_indices', workfolder );
1391   end
1392 return
1393 
1394 
1395 
1396 %------------------------------------------------------------------------------
1397 % Sub-function handling:
1398 %
1399 %    cloudbox_on
1400 %    cloudbox_limits
1401 %    pnd_field
1402 %    scat_data_array
1403 %    spt_calc_agenda
1404 %    opt_prop_gas_agenda
1405 %
1406 function T = cfile_CldBox( Q, partname, workfolder )
1407   %                                                                         %&%
1408   if ~( strcmp( partname, 'CldBox' )  |  strcmp( partname, 'CldBoxSave' ) ) %&%
1409     error( 'Only recognised choices are ''CldBox'' and ''CldBoxSave''.' );  %&%
1410   end                                                                       %&%
1411 
1412   if ~qarts_isset(Q.CLOUDBOX_DO)
1413      T={};
1414      return
1415   end
1416 
1417   rqre_datatype( Q.CLOUDBOX_DO, @isboolean, 'Q.CLOUDBOX_DO' );              %&%
1418   
1419   if ~Q.CLOUDBOX_DO
1420     T{1}     = 'cloudboxOff';
1421     T{end+1} = 'cloudbox_checkedCalc';
1422     return
1423   end
1424   
1425   if ~isstruct( Q.CLOUDBOX )                                                %&%
1426     error( 'Q.CLOUDBOX must be a structure if Q.CLOUD_BOX=1.' );            %&%
1427   end                                                                       %&%
1428 
1429   %= Check that all fields are present
1430   %
1431   qcheck( @qartsCloudbox, Q.CLOUDBOX );
1432 
1433   rqre_datatype( Q.CLOUDBOX.METHOD, @ischar, 'Q.CLOUDBOX.METHOD' );         %&%
1434   if ~any( strcmp( upper(Q.CLOUDBOX.METHOD), {'DOIT','MC','FOS','NONE'} ) ) %&%
1435     error( ...                                                              %&% 
1436        'Q.CLOUDBOX.METHOD must be ''DOIT'', ''MC'', ''FOS'' or ''none''.' ) %&%
1437   end                                                                       %&%
1438 
1439   %= Cloudbox
1440   %
1441   if qarts_isset (Q.CLOUDBOX.LIMITS)
1442     rqre_alltypes( Q.CLOUDBOX.LIMITS, {@isnumeric,@isvector}, ...           %&%
1443                                                     'Q.CLOUDBOX.LIMITS' );  %&%
1444     nlims = length(Q.CLOUDBOX.LIMITS);
1445     if  nlims < 6
1446       limits          = zeros(1,6);
1447       limits(1:nlims) = Q.CLOUDBOX.LIMITS;
1448     else
1449       limits = Q.CLOUDBOX.LIMITS(1:6);
1450     end
1451     T{1}     = 'cloudboxSetManuallyAltitude(';
1452     T{end+1} = '   cloudbox_on,cloudbox_limits,atmosphere_dim,z_field,';
1453     T{end+1} = sprintf( ...
1454             '   lat_grid,lon_grid,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f', limits );
1455     T{end+1} = ')';
1456   end
1457 
1458   if qarts_isset( Q.CLOUDBOX.PARTICLE_MASSES )
1459     T = file_or_data( T, 'particle_masses', 'Matrix', ...
1460                  Q.CLOUDBOX.PARTICLE_MASSES, workfolder, Q.INPUT_FILE_FORMAT );
1461   end
1462   
1463   %= Particle field and single scattering data
1464   %
1465   nset = qarts_isset(Q.CLOUDBOX.PND_FIELD) + qarts_isset(Q.CLOUDBOX.SCAT_DATA);
1466   %                                                                         %&%
1467   if nset == 1                                                              %&%
1468     error( 'Q.CLOUDBOX.PND_FIELD and Q.CLOUDBOX.SCAT_DATA must both ',...   %&%
1469                                     'be set, or both be undefined ({}).' ); %&%
1470   end                                                                       %&%
1471   if nset                                                                   
1472     if length(Q.CLOUDBOX.PND_FIELD) ~= length(Q.CLOUDBOX.SCAT_DATA)         %&%
1473       error( 'Q.CLOUDBOX.PND_FIELD and Q.CLOUDBOX.SCAT_DATA must have ',... %&%
1474                                                           'same length.' ); %&%
1475     end                                                                     %&%
1476     %
1477     T{end+1}  = 'ParticleTypeInit';
1478     do_pfCALC = false;
1479     %
1480     for i = 1 : length(Q.CLOUDBOX.PND_FIELD)
1481       if isstr( Q.CLOUDBOX.SCAT_DATA{i} )
1482         sfile = Q.CLOUDBOX.SCAT_DATA{i};
1483       else
1484         sfile = fullfile( workfolder, sprintf( 'scat_data_array_%d.xml', i ) );
1485         xmlStore( sfile, Q.CLOUDBOX.SCAT_DATA{i}, 'SingleScatteringData',...
1486                                                        Q.INPUT_FILE_FORMAT );
1487       end
1488       if isstr( Q.CLOUDBOX.PND_FIELD{i} )
1489         pfile = Q.CLOUDBOX.PND_FIELD{i};
1490       else
1491         pfile = fullfile( workfolder, sprintf( 'pnd_field_raw_%d.xml', i ) ); 
1492         xmlStore( pfile, Q.CLOUDBOX.PND_FIELD{i}, 'GriddedField3', ...
1493                                                        Q.INPUT_FILE_FORMAT );
1494       end
1495       %
1496       if length(pfile)
1497         do_pfCALC = true;
1498       end
1499       %
1500       T{end+1} = 'ParticleTypeAdd(';
1501       T{end+1} = sprintf('   filename_scat_data="%s",',sfile );
1502       T{end+1} = sprintf('   filename_pnd_field="%s")',pfile );
1503     end
1504     %
1505     if do_pfCALC 
1506       T{end+1} = 'pnd_fieldCalc';
1507     end
1508   end
1509   %
1510   T{end+1} = 'cloudbox_checkedCalc';
1511 
1512   %= Agendas for scattering properties
1513   %
1514   if qarts_isset(Q.CLOUDBOX.OPT_PROP_PART_AGENDA)
1515     T = add_agenda( T, 'opt_prop_part_agenda', Q.CLOUDBOX.OPT_PROP_PART_AGENDA);
1516   end
1517   if qarts_isset(Q.CLOUDBOX.SPT_CALC_AGENDA)
1518     T = add_agenda( T, 'spt_calc_agenda', Q.CLOUDBOX.SPT_CALC_AGENDA );
1519   end
1520 
1521   %= Saving?
1522   %
1523   if strcmp( partname, 'CldBoxSave' )
1524     T{end+1} = add_savefile( 'cloudbox_on', workfolder );
1525     T{end+1} = add_savefile( 'cloudbox_limits', workfolder );
1526     T{end+1} = add_savefile( 'pnd_field', workfolder );
1527     T{end+1} = add_savefile( 'scat_data_array', workfolder );
1528   end
1529 return
1530 
1531 
1532 
1533 %------------------------------------------------------------------------------
1534 % Sub-function handling:
1535 %
1536 %    variables for the different scattering methods
1537 %
1538 function T = cfile_SctMth( Q, partname, workfolder )
1539   %                                                                         %&%
1540   if ~( strcmp( partname, 'SctMth' )  |  ...                                %&%
1541         strcmp( partname, 'SctMthSave' )  |  ...                            %&%
1542         strcmp( partname, 'SctMthBatch' ) )                                 %&%
1543     error( ['Only recognised choices are ''SctMth'', ''SctMthSave'' ',...   %&%
1544             'and ''SctMthBatch''.'] );                                      %&%
1545   end                                                                       %&%
1546 
1547   if ~qarts_isset(Q.CLOUDBOX_DO)
1548      T={};
1549      return                           % Return
1550   else
1551     rqre_datatype( Q.CLOUDBOX_DO, @isboolean, 'Q.CLOUDBOX_DO' );            %&%
1552     if ~Q.CLOUDBOX_DO
1553       T={};
1554       return                           % Return
1555     end    
1556   end
1557   
1558   % It is assumed that cfile_CldBox has been called and checks of Q.CLOUDBOX
1559   % have been performed
1560 
1561   %= DOIT / MC
1562   %
1563   if strcmp( upper(Q.CLOUDBOX.METHOD), 'DOIT' )
1564     %
1565     rqre_field( Q.CLOUDBOX.METHOD_PRMTRS, {'N_ZA_GRID','N_AA_GRID',...      %&%
1566           'ZA_GRID_OPT_FILE', 'SCAT_ZA_INTERP', 'EPSILON', 'ALL_F' }, ...   %&%
1567                               'Q.CLOUDBOX.METHOD_PRMTRS when using DOIT' ); %&%
1568     rqre_alltypes( Q.CLOUDBOX.METHOD_PRMTRS.N_ZA_GRID, ...                  %&%
1569              {@istensor0,@iswhole}, 'Q.CLOUDBOX.METHOD_PRMTRS.N_ZA_GRID' ); %&%
1570     rqre_alltypes( Q.CLOUDBOX.METHOD_PRMTRS.N_AA_GRID, ...                  %&%
1571              {@istensor0,@iswhole}, 'Q.CLOUDBOX.METHOD_PRMTRS.N_AA_GRID' ); %&%
1572     rqre_datatype( Q.CLOUDBOX.METHOD_PRMTRS.SCAT_ZA_INTERP, @ischar, ...    %&%
1573                                'Q.CLOUDBOX.METHOD_PRMTRS.SCAT_ZA_INTERP' ); %&%
1574     if ~any( strcmp( Q.CLOUDBOX.METHOD_PRMTRS.SCAT_ZA_INTERP, ...           %&%
1575                                                {'linear','polynomial'} ) )  %&%
1576       error( ['Unknown interpolation method. ',...                          %&%
1577               'Q.CLOUDBOX.METHOD_PRMTRS.SCAT_ZA_INTERP can be ',...         %&%
1578               '''linear'' or ''polynomial''.'] );                           %&%
1579     end                                                                     %&%
1580     rqre_datatype( Q.CLOUDBOX.METHOD_PRMTRS.ZA_GRID_OPT_FILE, ...           %&%
1581        {@ischar,@istensor0}, 'Q.CLOUDBOX.METHOD_PRMTRS.ZA_GRID_OPT_FILE' ); %&%
1582     rqre_datatype( Q.CLOUDBOX.METHOD_PRMTRS.ALL_F, @isboolean, ...          %&%
1583                                         'Q.CLOUDBOX.METHOD_PRMTRS.ALL_F' ); %&%
1584     
1585     if isnumeric( Q.CLOUDBOX.METHOD_PRMTRS.ZA_GRID_OPT_FILE )      
1586       optfile = fullfile( workfolder, 'scat_za_grid.xml' ); 
1587       xmlStore( filename, Q.CLOUDBOX.METHOD_PRMTRS.ZA_GRID_OPT_FILE, ...
1588                                            'Vector', Q.INPUT_FILE_FORMAT );
1589     else     
1590       optfile = Q.CLOUDBOX.METHOD_PRMTRS.ZA_GRID_OPT_FILE;
1591     end
1592     
1593     T{1}     = sprintf( ...
1594                     'doit_za_interpSet(doit_za_interp,atmosphere_dim,"%s")', ...
1595                                       Q.CLOUDBOX.METHOD_PRMTRS.SCAT_ZA_INTERP );
1596     T{end+1} = 'DoitAngularGridsSet(';
1597     T{end+1} = '   doit_za_grid_size,scat_aa_grid,scat_za_grid,';
1598     T{end+1} = sprintf('   %d,%d,"%s"', Q.CLOUDBOX.METHOD_PRMTRS.N_ZA_GRID,...
1599                                 Q.CLOUDBOX.METHOD_PRMTRS.N_AA_GRID, optfile );
1600     T{end+1} = ')';
1601     %
1602     T = add_agenda( T, 'doit_mono_agenda', { ...
1603            'DoitScatteringDataPrepare', ...
1604            'doit_i_fieldSetClearsky(', ...
1605            '   doit_i_field,scat_i_p,scat_i_lat,scat_i_lon,f_grid,f_index', ...
1606            sprintf( ...
1607            '   p_grid,lat_grid,lon_grid,cloudbox_limits,atmosphere_dim,%d', ...
1608                                           Q.CLOUDBOX.METHOD_PRMTRS.ALL_F ), ...
1609            ')', ...
1610            'doit_i_fieldIterate',...
1611            'DoitCloudboxFieldPut' } ...
1612     );
1613     %
1614     T = add_agenda( T, 'pha_mat_spt_agenda', { ...
1615         'pha_mat_sptFromDataDOITOpt' } );
1616     
1617     if ischar( Q.CLOUDBOX.METHOD_PRMTRS.ZA_GRID_OPT_FILE )  &  ...
1618        strcmp( Q.CLOUDBOX.METHOD_PRMTRS.ZA_GRID_OPT_FILE, '""' )
1619       T = add_agenda( T, 'doit_scat_field_agenda', ...
1620                                              { 'doit_scat_fieldCalc' } );
1621     else
1622       T = add_agenda( T, 'doit_scat_field_agenda', ...
1623                                              { 'doit_scat_fieldCalcLimb' } );
1624     end
1625 
1626     if isfield( Q.CLOUDBOX.METHOD_PRMTRS, 'NORMALIZE' )
1627       T = add_agenda( T, 'doit_rte_agenda', { sprintf( ...
1628         'doit_i_fieldUpdateSeq%dD(normalize=%d,norm_error_threshold=%.3f)',...
1629                      Q.ATMOSPHERE_DIM, Q.CLOUDBOX.METHOD_PRMTRS.NORMALIZE, ...
1630                            Q.CLOUDBOX.METHOD_PRMTRS.NORM_ERROR_THRESHOLD ) } );
1631     else
1632       T = add_agenda( T, 'doit_rte_agenda', { sprintf( ...
1633                             'doit_i_fieldUpdateSeq%dD', Q.ATMOSPHERE_DIM ) } );
1634     end
1635     
1636     T = add_agenda( T, 'doit_conv_test_agenda', { ...
1637          'doit_conv_flagAbsBT(', ...
1638          '   doit_conv_flag,doit_iteration_counter,doit_i_field,', ...
1639          sprintf('   doit_i_field_old,f_grid,f_index,[%s]', ...
1640          vector2commalist(Q.CLOUDBOX.METHOD_PRMTRS.EPSILON(1:Q.STOKES_DIM))),...
1641          ')' } ...
1642         );
1643     T = add_agenda( T, 'iy_cloudbox_agenda', { 'Ignore(rtp_pos)', ...
1644                        'Ignore(rtp_los)', 'iyInterpCloudboxField' } );
1645 
1646     if ~strcmp( partname, 'SctMthBatch' )
1647       T{end+1} = 'sensor_checkedCalc';
1648       T{end+1} = 'CloudboxGetIncoming';
1649       T{end+1} = 'DoitInit';
1650       T{end+1} = 'ScatteringDoit';
1651     end
1652     
1653   elseif strcmp( upper(Q.CLOUDBOX.METHOD), 'MC' )
1654     %
1655     T = {};
1656     %
1657   elseif strcmp( upper(Q.CLOUDBOX.METHOD), 'FOS' )
1658     %
1659     T = {};
1660     %
1661   elseif strcmp( upper(Q.CLOUDBOX.METHOD), 'NONE' )
1662     %
1663     T = add_agenda( {}, 'iy_cloudbox_agenda', { 'Ignore(rtp_pos)', ...
1664                         'Ignore(rtp_los)', 'Ignore(f_grid)', 'Touch(iy)' } );
1665     %
1666   else                                                                      %&%
1667     error( 'Unknown choice for Q.CLOUDBOX.METHOD.' );                       %&%
1668   end
1669 
1670 return
1671 
1672 
1673 
1674 %------------------------------------------------------------------------------
1675 % Sub-function handling:
1676 %
1677 %    batch calculations
1678 %
1679 function T = cfile_BatchC( Q, partname, workfolder )
1680 
1681   error(' Batch part of *qarts2cfile* not updated.' );
1682   
1683   %- Some checks of data
1684   %
1685   if ~isstruct( Q.BATCH )
1686     error( 'Batch calculations can only be described by a structure.' );
1687   end
1688   %
1689   qcheck( @qartsBatch, Q.BATCH );
1690   %
1691   if length(Q.BATCH.DATA)  &  ~isstruct( Q.BATCH.DATA(1) )
1692     error( 'Q.BATCH.DATA must be a structure array.' );
1693   end
1694   %
1695   rqre_datatype( Q.BATCH.N, {@istensor0} );
1696 
1697   %- Store batch data and create batch_calc_agenda
1698   %
1699   T = [];
1700   A = [];
1701   %
1702   n_num = zeros(5,1);   % Number of "numeric" batch variables of different dim
1703   n_int = zeros(5,1);   % Same for index variables
1704   %
1705   for i = 1 : length( Q.BATCH.DATA )
1706     
1707     rqre_field( Q.BATCH.DATA(i), 'TYPE', 0 );
1708     rqre_char( sprintf('Q.BATCH{%d}.TYPE',i), Q.BATCH.DATA(i).TYPE );
1709     rqre_field( Q.BATCH.DATA(i), 'WSV', 0 );
1710     rqre_char( sprintf('Q.BATCH{%d}.WSV',i), Q.BATCH.DATA(i).WSV );
1711     rqre_field( Q.BATCH.DATA(i), 'X', 0 );
1712   
1713     %if size(Q.BATCH.DATA(i).X,1) < Q.BATCH.N
1714     %  error( sprintf( ...
1715     %         'Q.BATCH.DATA{%d}.X contains fewer cases than Q.BATCH.N', i ) );
1716     %end
1717 
1718     %- Determine dimensionality and type (num or int) of variable
1719     %
1720     [dim,datatype] = arts_datatypes( Q.BATCH.DATA(i).TYPE );
1721     %
1722     if strcmp(datatype,'num')
1723       n_num(dim) = n_num(dim) + 1;
1724       vn         = n_num(dim);      % "variable number"
1725     elseif strcmp(datatype,'int')
1726       n_int(dim) = n_int(dim) + 1;
1727       vn         = n_int(dim);      % "variable number"
1728     else
1729       vn         = 1;               % Assume only one variable of other types
1730     end
1731     
1732     mainname  = Q.BATCH.DATA(i).WSV;
1733     batchtype = arts_datatypes( dim+1, datatype );
1734     batchname = sprintf( '%s_%d', lower(batchtype), vn );
1735     
1736     T = file_or_data( T, batchname, batchtype, Q.BATCH.DATA(i).X, ...
1737          workfolder, Q.INPUT_FILE_FORMAT, sprintf('%s_batch.xml',mainname) );
1738     A{end+1} = sprintf( '%sExtractFrom%s(%s,%s,ybatch_index)', ...
1739                         Q.BATCH.DATA(i).TYPE, ...
1740                         batchtype, ...
1741                         mainname, ...
1742                         batchname );
1743   end
1744   %
1745   Arc = add_rtecalc( Q );
1746   A   = { A{:} Q.BATCH.WSM{:} Arc{:} };
1747   %
1748   T = add_agenda( T, 'ybatch_calc_agenda', A );
1749   
1750   %- Make actual calculations
1751   %
1752   T{end+1} = sprintf( 'IndexSet(ybatch_n){%d}', Q.BATCH.N );
1753   T{end+1} = 'ybatchCalc';
1754   %
1755   T{end+1} = add_savefile( 'ybatch', workfolder );
1756   
1757 return
1758 
1759 
1760 
1761 
1762 
1763 %------------------------------------------------------------------------------
1764 % Smaller help functions
1765 %------------------------------------------------------------------------------
1766 
1767 function s = create_var(artsvar,datatype)
1768   s = sprintf( '%sCreate(%s)', datatype, artsvar );
1769 return
1770 
1771 
1772 function T = file_or_data(T,artsvar,datatype,qvalue,workfolder,dformat,...
1773                                                                   nonDefFileId)
1774 
1775   % Check if string array with include cfile code. If yes, fill T and return.
1776   if iscellstr(qvalue)  &  length(qvalue) > 1  &  ...
1777      strcmp( qvalue{1}, 'Arts2{' )  &  strcmp( qvalue{end}, '}' )
1778 
1779     for i = 2 : length(qvalue)-1
1780       T{end+1} = qvalue{i};
1781     end
1782     return  % --->
1783   end
1784   
1785   if strcmp( datatype, 'Index' )                                           %&%
1786     rqre_datatype( qvalue, {@ischar,@iswhole}, ...                         %&%
1787                                     sprintf('The input for %s',artsvar) ); %&%
1788   elseif strcmp( datatype, 'Numeric' )                                     %&%
1789     rqre_datatype( qvalue, {@ischar,@istensor0}, ...                       %&%
1790                                     sprintf('The input for %s',artsvar) ); %&%
1791   elseif strcmp( datatype, 'Vector' )                                      %&%
1792     rqre_datatype( qvalue, {@ischar,@istensor1}, ...                       %&%
1793                                     sprintf('The input for %s',artsvar) ); %&%
1794   elseif strcmp( datatype, 'Matrix' )                                      %&%
1795     rqre_datatype( qvalue, {@ischar,@istensor2}, ...                       %&%
1796                                     sprintf('The input for %s',artsvar) ); %&%
1797   elseif strcmp( datatype, 'Tensor3' )                                     %&%
1798     rqre_datatype( qvalue, {@ischar,@istensor3}, ...                       %&%
1799                                     sprintf('The input for %s',artsvar) ); %&%
1800   elseif strcmp( datatype, 'Tensor4' )                                     %&%
1801     rqre_datatype( qvalue, {@ischar,@istensor4}, ...                       %&%
1802                                     sprintf('The input for %s',artsvar) ); %&%
1803   elseif strcmp( datatype, 'Sparse' )                                      %&%
1804     rqre_datatype( qvalue, {@ischar,@issparse}, ...                        %&%
1805                                     sprintf('The input for %s',artsvar) ); %&%
1806   elseif strcmp( datatype, 'String' )                                      %&%
1807     rqre_datatype( qvalue, {@ischar,@isempty}, ...                         %&%
1808                                     sprintf('The input for %s',artsvar) ); %&%
1809   elseif strcmp( datatype, 'ArrayOfString' )                               %&%
1810     rqre_datatype( qvalue, {@ischar,@isempty,@iscellstr,}, ...             %&%
1811                                     sprintf('The input for %s',artsvar) ); %&%
1812   % A generic check for remaining array types                              %&%
1813   elseif strncmp( datatype, 'ArrayOf', 7 )                                 %&%
1814     rqre_datatype( qvalue, {@ischar,@isempty,@iscell}, ...                 %&%
1815                                     sprintf('The input for %s',artsvar) ); %&%
1816   end                                                                      %&%
1817   
1818   % Determine if input data are a file
1819   isfile = ischar( qvalue );
1820   if strcmp( datatype, 'String' )       % Special handling of String vars.
1821     [p,n,ext] = fileparts( qvalue );  
1822     if ~strcmp( ext, {'xml','nc'} )
1823       isfile = false;
1824     end
1825   end
1826   
1827   if isfile
1828     T{end+1} = add_readfile( artsvar, qvalue );
1829   else
1830     if nargin > 6
1831       filename = fullfile( workfolder, [nonDefFileId,'.xml'] );
1832     else
1833       filename = fullfile( workfolder, [artsvar,'.xml'] );
1834     end
1835     xmlStore( filename, qvalue, datatype, dformat );
1836     T{end+1} = add_readfile( artsvar, filename );
1837   end
1838 return
1839 
1840 function s = add_readfile( artsvar, filename )
1841   [p,n,ext] = fileparts( filename );
1842   switch lower(ext)
1843    case '.xml'
1844      s = sprintf('ReadXML(%s,"%s")', artsvar, filename );
1845    case '.nc'
1846      s = sprintf('ReadNetCDF(%s,"%s")', artsvar, filename );     
1847    otherwise
1848     error( sprintf( ... 
1849     'Unknown file extension (%s), Allowed options are ''xml'' and ''nc''', ...
1850         ext ) );
1851   end
1852 return
1853 
1854 
1855 function s = add_savefile( artsvar, workfolder )
1856   filename = fullfile( workfolder, [ artsvar, '.xml' ] );
1857   s = sprintf('WriteXML(output_file_format,%s,"%s")', artsvar, filename );
1858 return
1859 
1860 
1861 function T = add_agenda( T, agenda, strarray )
1862   if ~iscellstr( strarray )                                                %&%
1863     error( sprintf( ...                                                    %&%
1864           'The agenda %s must be specified as cell array of strings.', ... %&%
1865                                                         upper(agenda) ) ); %&%
1866   end                                                                      %&%
1867   if length(strarray) == 1  &  ~isempty(strfind( strarray{1}, [agenda,'__'] ) )
1868     T{end+1} = sprintf( 'Copy(%s,%s)', agenda, strarray{1} );  
1869   else
1870     T{end+1} = sprintf( 'AgendaSet(%s){', agenda );
1871     for j = 1 : length(strarray)
1872       T{end+1} = sprintf( '   %s', strarray{j} );
1873     end
1874     T{end+1} = '}';
1875   end
1876 return
1877 
1878 
1879 function T = add_wsms( T, field, strarray, Q )
1880   if ~iscellstr( strarray )                                                %&%
1881     error( sprintf( ...                                                    %&%
1882            'The field %s must be specified as cell array of strings.', ... %&%
1883                                                                 field ) ); %&%
1884   end                                                                      %&%
1885   inif   = false;
1886   insert = true;
1887   for j = 1 : length(strarray)
1888     thisline = strarray{j};
1889     if length(thisline) > 0  &  thisline(1) == '<' 
1890       if strncmp( thisline, '<IF>', 4 )
1891         if length(thisline) < 5
1892           error( 'Empty <IF> found in %s.', field );
1893         end
1894         qfield = strtrim( thisline(5:end) );
1895         if ~qarts_isset( Q.(qfield) ) | ~isboolean(Q.(qfield))
1896           error( ['Incorrect usage of if-statement in %s. The argument (in ',...
1897                   'this case %s) must be a field of Q that is set and is ',  ...
1898                   'a boolean.'], field, qfield );
1899         end
1900         if Q.(qfield)
1901           insert = true;
1902         else
1903           insert = false;        
1904         end
1905         inif = true;
1906       elseif strncmp( thisline, '<ELSE>', 6 )
1907         if length( deblank( thisline ) ) ~= 6
1908           error( 'Incorrect line including <ELSE> found in %s.', field );
1909         end
1910         insert = ~insert;
1911       elseif strncmp( thisline, '<END>', 5 )
1912         if length( deblank( thisline ) ) ~= 5
1913           error( 'Incorrect line including <END> found in %s.', field );
1914         end
1915         inif   = false;
1916         insert = true;
1917       else
1918       end
1919     else    
1920       if insert
1921         T{end+1} = sprintf( '%s', strarray{j} );
1922       end
1923     end
1924   end
1925 return
1926 
1927 
1928 function T = add_includes( T, name, field )
1929   %
1930   if qarts_isset( field )
1931     if ~iscellstr( field )                                                 %&%
1932       error( sprintf('%s must be given as a cell array of strings.',...    %&%
1933                                                                   name) ); %&%
1934     end                                                                    %&%
1935     %
1936     arts_includes = atmlab( 'ARTS_INCLUDES' );
1937     %
1938     for i = 1 : length( field )
1939       if strfind( field{i}, 'ARTS_INCLUDES' )
1940         if isnan( arts_includes )                                          %&%
1941           error( ...                                                       %&%
1942            'Atmlab setting ARTS_INCLUDES is requested, but is not set.' ); %&%
1943         end                                                                %&%
1944         s = strrep( field{i}, 'ARTS_INCLUDES', arts_includes );
1945       else
1946         s = field{i};
1947       end
1948       T{end+1} = sprintf( 'INCLUDE "%s"', s );
1949     end
1950   end
1951 return
1952 
1953 
1954 function T = add_rtecalcstart( Q )
1955 
1956   T = {};
1957 
1958   %----------
1959   %- MC
1960   %----------
1961   if qarts_isset( Q.CLOUDBOX_DO )  &  Q.CLOUDBOX_DO  &  ...
1962                                         strcmp( upper(Q.CLOUDBOX.METHOD), 'MC' )
1963     %                                                                       %&%
1964     % Some checks of Q.CLOUDBOX performed already in cfile_CldBox           %&%
1965     %                                                                       %&%
1966     if ~isfield( Q.CLOUDBOX.METHOD_PRMTRS, 'STD_ERR' )  |  ...              %&%
1967        ~isfield( Q.CLOUDBOX.METHOD_PRMTRS, 'MAX_TIME' )  |  ...             %&%
1968        ~isfield( Q.CLOUDBOX.METHOD_PRMTRS, 'MAX_ITER' )  |  ...             %&%
1969        ~isfield( Q.CLOUDBOX.METHOD_PRMTRS, 'MIN_ITER' )                     %&%
1970       error( ['With Q.CLOUDBOX_DO=1 and MC method selected, ',...           %&%
1971            'CLOUDBOX.METHOD_PRMTRS must contain the fields: STD_ERR, ',...  %&%
1972               'MAX_TIME, MAX_ITER and MIN_ITER'] )                          %&%
1973     end                                                                     %&%
1974     %                                                                       %&%
1975     rqre_field( Q.CLOUDBOX.METHOD_PRMTRS, {'STD_ERR','MAX_TIME',...         %&%
1976                                        'MAX_ITER', 'MIN_ITER' }, ...        %&%
1977                                 'Q.CLOUDBOX.METHOD_PRMTRS when using MC' ); %&%
1978     rqre_datatype( Q.CLOUDBOX.METHOD_PRMTRS.STD_ERR, @istensor0, ...        %&%
1979                                       'Q.CLOUDBOX.METHOD_PRMTRS.STD_ERR' ); %&%
1980     rqre_datatype( Q.CLOUDBOX.METHOD_PRMTRS.MAX_TIME, @istensor0, ...       %&%
1981                                      'Q.CLOUDBOX.METHOD_PRMTRS.MAX_TIME' ); %&%
1982     rqre_datatype( Q.CLOUDBOX.METHOD_PRMTRS.MAX_ITER, @istensor0, ...       %&%
1983                                      'Q.CLOUDBOX.METHOD_PRMTRS.MAX_ITER' ); %&%
1984     rqre_datatype( Q.CLOUDBOX.METHOD_PRMTRS.MIN_ITER, @istensor0, ...       %&%
1985                                      'Q.CLOUDBOX.METHOD_PRMTRS.MIN_ITER' ); %&%
1986     %
1987     T{end+1} = sprintf( 'NumericSet(mc_std_err,%.3e)', ...
1988                                        Q.CLOUDBOX.METHOD_PRMTRS.STD_ERR );
1989     T{end+1} = sprintf( 'IndexSet(mc_max_time,%.0f)', ...
1990                                        Q.CLOUDBOX.METHOD_PRMTRS.MAX_TIME );
1991     T{end+1} = sprintf( 'IndexSet(mc_max_iter,%d)', ...
1992                                        Q.CLOUDBOX.METHOD_PRMTRS.MAX_ITER );
1993     T{end+1} = sprintf( 'IndexSet(mc_min_iter,%d)', ...
1994                                        Q.CLOUDBOX.METHOD_PRMTRS.MIN_ITER );
1995   end
1996 
1997   if qarts_isset( Q.WSMS_BEFORE_RTE )
1998     T = add_wsms( T, 'WSMS_BEFORE_RTE', Q.WSMS_BEFORE_RTE );
1999   end
2000 return  
2001 %------------------------------------------------------------------------------

Generated on Mon 15-Sep-2014 13:31:28 by m2html © 2005