0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072 function S = qarts2cfile( Q, parts, workfolder )
0073
0074
0075
0076
0077 if ~( nargin == 1 | nargin == 3 )
0078 error( 'The function takes 1 or 3 input arguments.' );
0079 end
0080
0081
0082
0083
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
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
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
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
0290
0291
0292
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
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
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
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
0471
0472
0473
0474
0475
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
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
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
0654
0655
0656
0657
0658
0659
0660
0661
0662
0663
0664
0665
0666
0667
0668
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
0751
0752
0753
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
0771
0772
0773
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
0787
0788
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
0801 end
0802
0803 rqre_datatype( Q.SENSOR_DO, @isboolean, 'Q.SENSOR_DO' );
0804 if ~Q.SENSOR_DO
0805 T{1} = 'sensorOff';
0806 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
0868
0869 if do_parts
0870
0871 H = Q.SENSOR_RESPONSE;
0872
0873 qcheck( @qartsSensor, H );
0874
0875
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
0899
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
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
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
1075
1076
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
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
1143 end
1144
1145
1146
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
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
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
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
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
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
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
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
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
1398
1399
1400
1401
1402
1403
1404
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
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
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
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
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
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
1535
1536
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
1550 else
1551 rqre_datatype( Q.CLOUDBOX_DO, @isboolean, 'Q.CLOUDBOX_DO' );
1552 if ~Q.CLOUDBOX_DO
1553 T={};
1554 return
1555 end
1556 end
1557
1558
1559
1560
1561
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
1676
1677
1678
1679 function T = cfile_BatchC( Q, partname, workfolder )
1680
1681 error(' Batch part of *qarts2cfile* not updated.' );
1682
1683
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
1698
1699 T = [];
1700 A = [];
1701
1702 n_num = zeros(5,1);
1703 n_int = zeros(5,1);
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
1714
1715
1716
1717
1718
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);
1725 elseif strcmp(datatype,'int')
1726 n_int(dim) = n_int(dim) + 1;
1727 vn = n_int(dim);
1728 else
1729 vn = 1;
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
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
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
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
1813 elseif strncmp( datatype, 'ArrayOf', 7 )
1814 rqre_datatype( qvalue, {@ischar,@isempty,@iscell}, ...
1815 sprintf('The input for %s',artsvar) );
1816 end
1817
1818
1819 isfile = ischar( qvalue );
1820 if strcmp( datatype, 'String' )
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
1960
1961 if qarts_isset( Q.CLOUDBOX_DO ) & Q.CLOUDBOX_DO & ...
1962 strcmp( upper(Q.CLOUDBOX.METHOD), 'MC' )
1963
1964
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