cloudy
trunk
|
00001 /* This file is part of Cloudy and is copyright (C)1978-2008 by Gary J. Ferland and 00002 * others. For conditions of distribution and use see copyright notice in license.txt */ 00003 /*ParseOptimize parse the optimize and grid command lines */ 00004 /*GetOptColDen read observed column densities & errors for optimizer */ 00005 /*GetOptLineInt parse observed line intensities for optimization routines */ 00006 /*GetOptTemp read observed temperatures & errors for optimizer */ 00007 #include "cddefines.h" 00008 #include "trace.h" 00009 #include "optimize.h" 00010 #include "grid.h" 00011 #include "input.h" 00012 #include "prt.h" 00013 #include "parse.h" 00014 #include "lines_service.h" 00015 00016 static const realnum DEFERR = 0.05f; 00017 00018 /*GetOptLineInt parse observed line intensities for optimization routines */ 00019 STATIC void GetOptLineInt(char *chCard ); 00020 00021 /*GetOptColDen read observed column densities & errors for optimizer */ 00022 STATIC void GetOptColDen(char *chCard ); 00023 00024 /*GetOptTemp read observed temperatures & errors for optimizer */ 00025 STATIC void GetOptTemp(char *chCard ); 00026 00027 /* ParseOptimize - called from ParseCommands if GRID or OPTIMIZE command found */ 00028 void ParseOptimize( 00029 /* command line, which was changed to all caps in main parsing routine */ 00030 char *chCard) 00031 { 00032 bool lgEOL; 00033 long int i; 00034 00035 DEBUG_ENTRY( "ParseOptimize()" ); 00036 00037 /* this must come first so that contents of filename do not trigger wrong command */ 00038 if( nMatch("FILE",chCard) ) 00039 { 00040 /* option to send final set of parameters to an input file 00041 * get name within double quotes, 00042 * and set to blanks in chCard and OrgCard */ 00043 /* file handle set NULL in optimize_do when first set up, 00044 * this routine called many times during optimization process, 00045 * only want to open file one time */ 00046 if( optimize.ioOptim == NULL ) 00047 { 00048 /* chCard is all caps at this point. GetQuote will work with 00049 * original version of command line, which preserves case of 00050 * characters. Also removes string between quotes */ 00051 if( GetQuote( chOptimFileName , chCard , true ) ) 00052 /* this can't happen since GetQuote exits if quote not 00053 * found, since true sets abort mode */ 00054 TotalInsanity(); 00055 00056 /* open the file */ 00057 optimize.ioOptim = open_data( chOptimFileName, "w", AS_LOCAL_ONLY ); 00058 } 00059 } 00060 00061 else if( nMatch("COLU",chCard) ) 00062 { 00063 /* optimize column density */ 00064 optimize.lgOptCol = true; 00065 optimize.lgOptimize = true; 00066 00067 /* read column densities to match */ 00068 GetOptColDen(chCard); 00069 } 00070 00071 else if( nMatch("CONT",chCard) ) 00072 { 00073 /* set flag saying that optimization should start from continue file */ 00074 optimize.lgOptCont = true; 00075 optimize.lgOptimize = true; 00076 } 00077 00078 /* >>chng 06 sep 4, exclude lines with "GRID", handled below. */ 00079 else if( nMatch("INCR",chCard) && !nMatch("GRID",chCard) ) 00080 { 00081 /* scan off increments for the previously selected parameter */ 00082 if( optimize.nparm > 0 ) 00083 { 00084 /* also called during optimization process, ignore then */ 00085 i = 5; 00086 optimize.OptIncrm[optimize.nparm-1] = 00087 (realnum)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL); 00088 } 00089 } 00090 00091 else if( nMatch("LUMI",chCard) || nMatch("INTE",chCard) ) 00092 { 00093 /* scan off intensity or luminosity of normalization line */ 00094 i = 5; 00095 optimize.optint = (realnum)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL); 00096 optimize.optier = (realnum)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL); 00097 if( lgEOL ) 00098 optimize.optier = DEFERR; 00099 00100 /* set flag to say that intensity or luminosity of line set */ 00101 optimize.lgOptLum = true; 00102 optimize.lgOptimize = true; 00103 } 00104 00105 else if( nMatch("ITER",chCard) ) 00106 { 00107 /* scan off number of iterations */ 00108 i = 5; 00109 optimize.nIterOptim = (long)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL); 00110 } 00111 00112 else if( nMatch("LINE",chCard) ) 00113 { 00114 /* read lines to match */ 00115 GetOptLineInt(chCard); 00116 00117 /* set flag saying that something has been set */ 00118 optimize.lgOptLin = true; 00119 optimize.lgOptimize = true; 00120 } 00121 00122 else if( nMatch("PHYM",chCard) ) 00123 { 00124 /* use PvH's PHYMIR to optimize parameters */ 00125 strcpy( optimize.chOptRtn, "PHYM" ); 00126 # ifdef __unix 00127 optimize.lgParallel = ! nMatch("SEQU",chCard); 00128 # else 00129 optimize.lgParallel = false; 00130 # endif 00131 if( optimize.lgParallel ) 00132 { 00133 i = 5; 00134 long dum = (long)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL); 00135 /* default is the total number of available CPUs */ 00136 optimize.useCPU = lgEOL ? cpu.nCPU() : dum; 00137 } 00138 else 00139 { 00140 optimize.useCPU = 1; 00141 } 00142 } 00143 00144 /* >>chng 06 aug 22, grid now done differently, requires two range parameters 00145 * and the number of points, parsed below as "GRID". */ 00146 else if( nMatch("RANG",chCard) && !nMatch("GRID",chCard) ) 00147 { 00148 /* scan off range for the previously selected variable */ 00149 if( optimize.nparm > 0 ) 00150 { 00151 bool lgFirstOneReal = false; 00152 00153 i = 5; 00154 optimize.varang[optimize.nparm-1][0] = 00155 (realnum)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL); 00156 if( lgEOL ) 00157 { 00158 optimize.varang[optimize.nparm-1][0] = -1e38f; 00159 } 00160 else 00161 { 00162 lgFirstOneReal = true; 00163 } 00164 00165 optimize.varang[optimize.nparm-1][1] = 00166 (realnum)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL); 00167 if( lgEOL ) 00168 { 00169 optimize.varang[optimize.nparm-1][1] = 1e38f; 00170 } 00171 else if( lgFirstOneReal ) 00172 { 00173 /* >>chng 06 aug 22, swap if second range parameter is less than the first, 00174 * and always increment optimize.nRangeSet */ 00175 ++optimize.nRangeSet; 00176 if( optimize.varang[optimize.nparm-1][1] < optimize.varang[optimize.nparm-1][0] ) 00177 { 00178 realnum temp = optimize.varang[optimize.nparm-1][0]; 00179 optimize.varang[optimize.nparm-1][0] = optimize.varang[optimize.nparm-1][1]; 00180 optimize.varang[optimize.nparm-1][1] = temp; 00181 } 00182 } 00183 } 00184 } 00185 00186 else if( nMatch("SUBP",chCard) ) 00187 { 00188 /* use subplex to optimize parameters */ 00189 strcpy( optimize.chOptRtn, "SUBP" ); 00190 } 00191 00192 /* match a temperature */ 00193 else if( nMatch("TEMP",chCard) ) 00194 { 00195 /* read temperatures to match */ 00196 GetOptTemp(chCard); 00197 00198 /* set flag saying that optimize temps has been set */ 00199 optimize.lgOptTemp = true; 00200 optimize.lgOptimize = true; 00201 } 00202 00203 else if( nMatch("TOLE",chCard) ) 00204 { 00205 /* scan off tolerance of fit, sum of residuals must be smaller than this 00206 * default is 0.10 */ 00207 i = 5; 00208 optimize.OptGlobalErr = (realnum)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL); 00209 } 00210 00211 else if( nMatch("TRAC",chCard) ) 00212 { 00213 if( nMatch("STAR",chCard) ) 00214 { 00215 /* trace start iteration number 00216 * turn on trace printout starting on nth call to cloudy */ 00217 i = 5; 00218 optimize.nTrOpt = (long)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL); 00219 if( lgEOL ) 00220 { 00221 fprintf( ioQQQ, " optimize trace start command:\n" ); 00222 fprintf( ioQQQ, " The iteration number must appear.\n" ); 00223 cdEXIT(EXIT_FAILURE); 00224 } 00225 optimize.lgTrOpt = true; 00226 } 00227 else if( nMatch("FLOW",chCard) ) 00228 { 00229 /* trace flow 00230 * follow logical flow within code */ 00231 optimize.lgOptimFlow = true; 00232 } 00233 else 00234 { 00235 fprintf( ioQQQ, " optimize trace flow command:\n" ); 00236 fprintf( ioQQQ, " One of the sub keys START or FLOW must appear.\n" ); 00237 cdEXIT(EXIT_FAILURE); 00238 } 00239 } 00240 00241 else 00242 { 00243 fprintf( ioQQQ, " ==%s== is unrecognized keyword, consult HAZY.\n", chCard ); 00244 cdEXIT(EXIT_FAILURE); 00245 } 00246 return; 00247 } 00248 00249 /*GetOptColDen read observed column densities & errors for optimizer */ 00250 STATIC void GetOptColDen(char *chCard ) 00251 { 00252 char chCap[INPUT_LINE_LENGTH]; 00253 bool lgEOF, 00254 lgEOL; 00255 long int i; 00256 00257 DEBUG_ENTRY( "GetOptColDen()" ); 00258 00259 /* read observed column densities & errors */ 00260 optimize.ncobs = 0; 00261 00262 /* get first line */ 00263 input_readarray(chCard,&lgEOF); 00264 if( lgEOF ) 00265 { 00266 fprintf( ioQQQ, " Hit EOF while reading column density list; use END to end list.\n" ); 00267 cdEXIT(EXIT_FAILURE); 00268 } 00269 00270 /* now copy this line to chCap, then convert to caps */ 00271 strcpy( chCap, chCard ); 00272 caps(chCap); 00273 00274 while( !lgEOF ) 00275 { 00276 if( optimize.ncobs > NCOLLM ) 00277 { 00278 fprintf( ioQQQ, " Too many column densities have been entered; the limit is%4ld. Increase variable NCOLLM.\n", 00279 NCOLLM ); 00280 cdEXIT(EXIT_FAILURE); 00281 } 00282 00283 /* order on line is element label (col 1-4), ionization stage, column density, err */ 00284 /* copy cap'd version of first 4 char of chCard to chColDen_label */ 00285 cap4((char*)optimize.chColDen_label[optimize.ncobs] , chCard ); 00286 00287 /* now get the ion stage, this should be 1 for atom, up to element 00288 * number plus one */ 00289 i = 5; 00290 optimize.ion_ColDen[optimize.ncobs] = (long int)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL); 00291 if( lgEOL ) 00292 { 00293 fprintf( ioQQQ, " %s\n", chCard ); 00294 fprintf( ioQQQ, " The ionization stage MUST appear on this line. Sorry.\n" ); 00295 cdEXIT(EXIT_FAILURE); 00296 } 00297 00298 /* the ion must be 1 or greater unless requesting a special, 00299 * like a molecule or excited state population, in which 00300 * case ion = 0 00301 * can't check on upper limit yet since have not resolved element name */ 00302 if( optimize.ion_ColDen[optimize.ncobs] < 0 ) 00303 { 00304 fprintf( ioQQQ, " %s\n", chCard ); 00305 fprintf( ioQQQ, " An ionization stage of%4ld does not make sense. Sorry.\n", 00306 optimize.ion_ColDen[optimize.ncobs] ); 00307 cdEXIT(EXIT_FAILURE); 00308 } 00309 00310 optimize.ColDen_Obs[optimize.ncobs] = (realnum)pow(10.,FFmtRead(chCard,&i, 00311 INPUT_LINE_LENGTH,&lgEOL)); 00312 if( lgEOL ) 00313 { 00314 fprintf( ioQQQ, " %80.80s\n", chCard ); 00315 fprintf( ioQQQ, " An observed column density MUST be entered. Sorry.\n" ); 00316 cdEXIT(EXIT_FAILURE); 00317 } 00318 00319 optimize.chColDen_error[optimize.ncobs] = (realnum)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL); 00320 if( optimize.chColDen_error[optimize.ncobs] <= 0.0 ) 00321 { 00322 /* this is the relative error allowed */ 00323 optimize.chColDen_error[optimize.ncobs] = (realnum)DEFERR; 00324 } 00325 00326 /* check if number is a limit - if '<' appears on the line then it is */ 00327 if( strchr( chCard , '<' ) != NULL ) 00328 { 00329 /* value is an upper limit only, use negative error to flag */ 00330 optimize.chColDen_error[optimize.ncobs] = -optimize.chColDen_error[optimize.ncobs]; 00331 } 00332 00333 input_readarray(chCard,&lgEOF); 00334 strcpy( chCap, chCard ); 00335 caps(chCap); 00336 if( lgEOF ) 00337 { 00338 fprintf( ioQQQ, " Hit EOF while reading column density list; use END to end list.\n" ); 00339 cdEXIT(EXIT_FAILURE); 00340 } 00341 00342 if( strncmp( chCap , "END" , 3) == 0 ) 00343 { 00344 lgEOF = true; 00345 } 00346 00347 /* now increment the number of columns we have entered */ 00348 optimize.ncobs += 1; 00349 } 00350 00351 if( trace.lgTrace && optimize.lgTrOpt ) 00352 { 00353 fprintf( ioQQQ, "%4ld columns were entered, they were;\n", 00354 optimize.ncobs ); 00355 for( i=0; i < optimize.ncobs; i++ ) 00356 { 00357 fprintf( ioQQQ, " %4.4s ion=%5ld%10.2e%10.2e\n", 00358 optimize.chColDen_label[i], optimize.ion_ColDen[i], optimize.ColDen_Obs[i], 00359 optimize.chColDen_error[i] ); 00360 } 00361 } 00362 return; 00363 } 00364 00365 /*GetOptLineInt parse observed line intensities for optimization routines */ 00366 STATIC void GetOptLineInt(char *chCard ) 00367 { 00368 char chCap[INPUT_LINE_LENGTH]; 00369 00370 bool lgEOF, 00371 lgEOL; 00372 long int i; 00373 00374 DEBUG_ENTRY( "GetOptLineInt()" ); 00375 00376 /* read observed line fluxes & errors */ 00377 optimize.nlobs = 0; 00378 00379 input_readarray(chCard,&lgEOF); 00380 if( lgEOF ) 00381 { 00382 fprintf( ioQQQ, " Hit EOF while reading line list; use END to end list.\n" ); 00383 cdEXIT(EXIT_FAILURE); 00384 } 00385 00386 strcpy( chCap, chCard ); 00387 caps(chCap); 00388 00389 while( !lgEOF ) 00390 { 00391 if( optimize.nlobs >= NOBSLM ) 00392 { 00393 fprintf( ioQQQ, 00394 " Too many lines have been entered; the limit is %ld. Increase variable NOBSLM.\n", 00395 NOBSLM ); 00396 cdEXIT(EXIT_FAILURE); 00397 } 00398 00399 /* order on line is label (col 1-4), wavelength, flux, error */ 00400 strncpy( optimize.chLineLabel[optimize.nlobs], chCard , 4 ); 00401 /* null terminate the label*/ 00402 optimize.chLineLabel[optimize.nlobs][4] = 0; 00403 00404 i = 5; 00405 /* next get the wavelength */ 00406 optimize.wavelength[optimize.nlobs] = (realnum)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL); 00407 00408 /* now convert wavelength to angstroms */ 00409 /* line was entered, look for possible micron or cm label */ 00410 if( input.chCARDCAPS[i-1] == 'M' ) 00411 { 00412 /* microns */ 00413 optimize.wavelength[optimize.nlobs] *= 1e4f; 00414 } 00415 else if( input.chCARDCAPS[i-1] == 'C' ) 00416 { 00417 /* microns */ 00418 optimize.wavelength[optimize.nlobs] *= 1e8f; 00419 } 00420 00421 /* get the error associated with 4 significant figures */ 00422 optimize.errorwave[optimize.nlobs] = 00423 WavlenErrorGet( optimize.wavelength[optimize.nlobs] ); 00424 00425 /* next get the observed intensity */ 00426 optimize.xLineInt_Obs[optimize.nlobs] = (realnum)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL); 00427 if( lgEOL ) 00428 { 00429 fprintf( ioQQQ, " %s\n", chCard ); 00430 fprintf( ioQQQ, " The wavelength and relative intensity MUST be entered on this line. Sorry.\n" ); 00431 fprintf( ioQQQ, " The command line is the following:\n %s\n", chCard ); 00432 cdEXIT(EXIT_FAILURE); 00433 } 00434 00435 if( optimize.xLineInt_Obs[optimize.nlobs] <= 0. ) 00436 { 00437 fprintf( ioQQQ, " An observed intensity of %.2e is not allowed. Sorry.\n", 00438 optimize.xLineInt_Obs[optimize.nlobs] ); 00439 fprintf( ioQQQ, " The command line is the following:\n %s\n", chCard ); 00440 cdEXIT(EXIT_FAILURE); 00441 } 00442 00443 /* finally the optional error */ 00444 optimize.xLineInt_error[optimize.nlobs] = (realnum)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL); 00445 /* most often will use the default */ 00446 if( optimize.xLineInt_error[optimize.nlobs] <= 0.0 ) 00447 { 00448 /* this is the relative error allowed */ 00449 optimize.xLineInt_error[optimize.nlobs] = (realnum)DEFERR; 00450 } 00451 00452 /* check if number is a limit - if '<' appears on the line then it is */ 00453 if( strchr( chCard , '<' ) != NULL ) 00454 { 00455 /* value is an upper limit only, use negative error to flag */ 00456 optimize.xLineInt_error[optimize.nlobs] = -optimize.xLineInt_error[optimize.nlobs]; 00457 } 00458 00459 /* get next line */ 00460 input_readarray(chCard,&lgEOF); 00461 if( lgEOF ) 00462 { 00463 fprintf( ioQQQ, " Hit EOF while reading line list for optimize command; use END to end list.\n" ); 00464 cdEXIT(EXIT_FAILURE); 00465 } 00466 00467 strcpy( chCap, chCard ); 00468 caps(chCap); 00469 if( strncmp( chCap ,"END" , 3 ) == 0 ) 00470 lgEOF = true; 00471 00472 /* finally increment the number of observed lines */ 00473 ++optimize.nlobs; 00474 } 00475 00476 if( trace.lgTrace && trace.lgTrOptm ) 00477 { 00478 fprintf( ioQQQ, "%4ld lines were entered, they were;\n", 00479 optimize.nlobs ); 00480 00481 for( i=0; i < optimize.nlobs; i++ ) 00482 { 00483 fprintf( ioQQQ, " %4.4s ", optimize.chLineLabel[i] ); 00484 prt_wl( ioQQQ, optimize.wavelength[i] ); 00485 00486 fprintf( ioQQQ, " %10.2e%10.2e\n", 00487 optimize.xLineInt_Obs[i], 00488 optimize.xLineInt_error[i] ); 00489 } 00490 } 00491 return; 00492 } 00493 00494 /*GetOptTemp parse observed line intensities for optimization routines */ 00495 STATIC void GetOptTemp(char *chCard ) 00496 { 00497 char chCap[INPUT_LINE_LENGTH]; 00498 00499 bool lgEOF, 00500 lgEOL; 00501 long int i; 00502 00503 DEBUG_ENTRY( "GetOptTemp()" ); 00504 00505 /* read observed line fluxes & errors - first set total number of observe temps */ 00506 optimize.nTempObs = 0; 00507 00508 input_readarray(chCard,&lgEOF); 00509 if( lgEOF ) 00510 { 00511 fprintf( ioQQQ, " Hit EOF while reading line list; use END to end list.\n" ); 00512 cdEXIT(EXIT_FAILURE); 00513 } 00514 00515 /* make line caps so we can parse it */ 00516 strcpy( chCap, chCard ); 00517 caps(chCap); 00518 00519 while( !lgEOF ) 00520 { 00521 if( optimize.nTempObs >= NOBSLM ) 00522 { 00523 fprintf( ioQQQ, 00524 " Too many temperatures have been entered; the limit is %ld. Increase variable NOBSLM.\n", 00525 NOBSLM ); 00526 cdEXIT(EXIT_FAILURE); 00527 } 00528 00529 /* order on line is label (col 1-4), ion, temperature, error */ 00530 strncpy( optimize.chTempLab[optimize.nTempObs], chCard , 4 ); 00531 /* null terminate the label*/ 00532 optimize.chTempLab[optimize.nTempObs][4] = 0; 00533 00534 i = 5; 00535 /* next get the ion stage */ 00536 optimize.ionTemp[optimize.nTempObs] = (long)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL); 00537 00538 /* next get the observed temperature */ 00539 optimize.temp_obs[optimize.nTempObs] = (realnum)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL); 00540 if( lgEOL ) 00541 { 00542 fprintf( ioQQQ, " %s\n", chCard ); 00543 fprintf( ioQQQ, " The ion stage and temperature MUST be entered on this line. Sorry.\n" ); 00544 fprintf( ioQQQ, " The command line is the following:\n %s\n", chCard ); 00545 cdEXIT(EXIT_FAILURE); 00546 } 00547 00548 /* temperatures less than or equal to 10 are logs */ 00549 if( optimize.temp_obs[optimize.nTempObs] <= 10. ) 00550 { 00551 optimize.temp_obs[optimize.nTempObs] = (realnum)pow( 10. , (double)optimize.temp_obs[optimize.nTempObs] ); 00552 } 00553 00554 /* finally the optional error */ 00555 optimize.temp_error[optimize.nTempObs] = (realnum)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL); 00556 /* most often will use the default */ 00557 if( optimize.temp_error[optimize.nTempObs] <= 0.0 ) 00558 { 00559 /* this is the relative error allowed */ 00560 optimize.temp_error[optimize.nTempObs] = (realnum)DEFERR; 00561 } 00562 00563 /* check if number is a limit - if '<' appears on the line then it is */ 00564 if( strchr( chCard , '<' ) != NULL ) 00565 { 00566 /* value is an upper limit only, use negative error to flag */ 00567 optimize.temp_error[optimize.nTempObs] = -optimize.temp_error[optimize.nTempObs]; 00568 } 00569 00570 /* check for radius or volume for how to weight the mean temp 00571 * this will be the default */ 00572 strcpy( optimize.chTempWeight[optimize.nTempObs] , "radius" ); 00573 /* >>chng 05 dec 29, from chCard to chCap, unlike much of code in this file, 00574 * chCard has been read in by this routine and contains the original form of 00575 * the command line. It was converted to caps and stored in chCap above. 00576 * As it was written only VOLUME was matched, would not match volume. 00577 * Bug caught and corrected by Bohdan Melekh */ 00578 /*if( nMatch( "VOLUME" , chCard ) )*/ 00579 if( nMatch( "VOLUME" , chCap ) ) 00580 { 00581 strcpy( optimize.chTempWeight[optimize.nTempObs] , "volume" ); 00582 } 00583 00584 /* get next line */ 00585 input_readarray(chCard,&lgEOF); 00586 if( lgEOF ) 00587 { 00588 fprintf( ioQQQ, " Hit EOF while reading line list for optimize command; use END to end list.\n" ); 00589 cdEXIT(EXIT_FAILURE); 00590 } 00591 00592 strcpy( chCap, chCard ); 00593 caps(chCap); 00594 if( strncmp( chCap ,"END" , 3 ) == 0 ) 00595 lgEOF = true; 00596 00597 /* finally increment the number of observed lines */ 00598 ++optimize.nTempObs; 00599 } 00600 00601 if( trace.lgTrace && trace.lgTrOptm ) 00602 { 00603 fprintf( ioQQQ, "%4ld temperatures were entered, they were;\n", 00604 optimize.nTempObs ); 00605 00606 for( i=0; i < optimize.nTempObs; i++ ) 00607 { 00608 fprintf( ioQQQ, " %4.4s ", optimize.chTempLab[i] ); 00609 fprintf( ioQQQ, " %li " , optimize.ionTemp[i] ); 00610 00611 fprintf( ioQQQ, " %.2e %.2e\n", 00612 optimize.temp_obs[i], 00613 optimize.temp_error[i] ); 00614 } 00615 } 00616 return; 00617 }