00001 
00002 
00003 
00004 
00005 
00006 
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 
00019 STATIC void GetOptLineInt(char *chCard );
00020 
00021 
00022 STATIC void GetOptColDen(char *chCard );
00023 
00024 
00025 STATIC void GetOptTemp(char *chCard );
00026 
00027 
00028 void ParseOptimize(
00029         
00030         char *chCard)
00031 {
00032         bool lgEOL;
00033         long int i;
00034 
00035         DEBUG_ENTRY( "ParseOptimize()" );
00036 
00037         
00038         if( nMatch("FILE",chCard) )
00039         {
00040                 
00041 
00042 
00043                 
00044 
00045 
00046                 if( optimize.ioOptim == NULL )
00047                 {
00048                         
00049 
00050 
00051                         if( GetQuote( chOptimFileName , chCard , true ) )
00052                                 
00053 
00054                                 TotalInsanity();
00055 
00056                         
00057                         optimize.ioOptim = open_data( chOptimFileName, "w", AS_LOCAL_ONLY );
00058                 }
00059         }
00060 
00061         else if( nMatch("COLU",chCard) )
00062         {
00063                 
00064                 optimize.lgOptCol = true;
00065                 optimize.lgOptimize = true;
00066 
00067                 
00068                 GetOptColDen(chCard);
00069         }
00070 
00071         else if( nMatch("CONT",chCard) )
00072         {
00073                 
00074                 optimize.lgOptCont = true;
00075                 optimize.lgOptimize = true;
00076         }
00077 
00078         
00079         else if( nMatch("INCR",chCard) && !nMatch("GRID",chCard) )
00080         {
00081                 
00082                 if( optimize.nparm > 0 )
00083                 {
00084                         
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                 
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                 
00101                 optimize.lgOptLum = true;
00102                 optimize.lgOptimize = true;
00103         }
00104 
00105         else if( nMatch("ITER",chCard) )
00106         {
00107                 
00108                 i = 5;
00109                 optimize.nIterOptim = (long)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL);
00110         }
00111 
00112         else if( nMatch("LINE",chCard) )
00113         {
00114                 
00115                 GetOptLineInt(chCard);
00116 
00117                 
00118                 optimize.lgOptLin = true;
00119                 optimize.lgOptimize = true;
00120         }
00121 
00122         else if( nMatch("PHYM",chCard) )
00123         {
00124                 
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                         
00136                         optimize.useCPU = lgEOL ? cpu.nCPU() : dum;
00137                 }
00138                 else 
00139                 {
00140                         optimize.useCPU = 1;
00141                 }
00142         }
00143 
00144         
00145 
00146         else if( nMatch("RANG",chCard) && !nMatch("GRID",chCard)  )
00147         {
00148                 
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                                 
00174 
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                 
00189                 strcpy( optimize.chOptRtn, "SUBP" );
00190         }
00191 
00192         
00193         else if( nMatch("TEMP",chCard) )
00194         {
00195                 
00196                 GetOptTemp(chCard);
00197 
00198                 
00199                 optimize.lgOptTemp = true;
00200                 optimize.lgOptimize = true;
00201         }
00202 
00203         else if( nMatch("TOLE",chCard) )
00204         {
00205                 
00206 
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                         
00216 
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                         
00230 
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 
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         
00260         optimize.ncobs = 0;
00261 
00262         
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         
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                 
00284                 
00285                 cap4((char*)optimize.chColDen_label[optimize.ncobs] , chCard );
00286 
00287                 
00288 
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                 
00299 
00300 
00301 
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                         
00323                         optimize.chColDen_error[optimize.ncobs] = (realnum)DEFERR;
00324                 }
00325 
00326                 
00327                 if( strchr( chCard , '<' ) != NULL )
00328                 {
00329                         
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                 
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 
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         
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                 
00400                 strncpy( optimize.chLineLabel[optimize.nlobs], chCard , 4 );
00401                 
00402                 optimize.chLineLabel[optimize.nlobs][4] = 0;
00403 
00404                 i = 5;
00405                 
00406                 optimize.wavelength[optimize.nlobs] = (realnum)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL);
00407 
00408                 
00409                 
00410                 if( input.chCARDCAPS[i-1] == 'M' )
00411                 {
00412                         
00413                         optimize.wavelength[optimize.nlobs] *= 1e4f;
00414                 }
00415                 else if( input.chCARDCAPS[i-1] == 'C' )
00416                 {
00417                         
00418                         optimize.wavelength[optimize.nlobs] *= 1e8f;
00419                 }
00420 
00421                 
00422                 optimize.errorwave[optimize.nlobs] = 
00423                         WavlenErrorGet( optimize.wavelength[optimize.nlobs] );
00424 
00425                 
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                 
00444                 optimize.xLineInt_error[optimize.nlobs] = (realnum)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL);
00445                 
00446                 if( optimize.xLineInt_error[optimize.nlobs] <= 0.0 )
00447                 {
00448                         
00449                         optimize.xLineInt_error[optimize.nlobs] = (realnum)DEFERR;
00450                 }
00451 
00452                 
00453                 if( strchr( chCard , '<' ) != NULL )
00454                 {
00455                         
00456                         optimize.xLineInt_error[optimize.nlobs] = -optimize.xLineInt_error[optimize.nlobs];
00457                 }
00458 
00459                 
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                 
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 
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         
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         
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                 
00530                 strncpy( optimize.chTempLab[optimize.nTempObs], chCard , 4 );
00531                 
00532                 optimize.chTempLab[optimize.nTempObs][4] = 0;
00533 
00534                 i = 5;
00535                 
00536                 optimize.ionTemp[optimize.nTempObs] = (long)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL);
00537 
00538                 
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                 
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                 
00555                 optimize.temp_error[optimize.nTempObs] = (realnum)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL);
00556                 
00557                 if( optimize.temp_error[optimize.nTempObs] <= 0.0 )
00558                 {
00559                         
00560                         optimize.temp_error[optimize.nTempObs] = (realnum)DEFERR;
00561                 }
00562 
00563                 
00564                 if( strchr( chCard , '<' ) != NULL )
00565                 {
00566                         
00567                         optimize.temp_error[optimize.nTempObs] = -optimize.temp_error[optimize.nTempObs];
00568                 }
00569 
00570                 
00571 
00572                 strcpy( optimize.chTempWeight[optimize.nTempObs] , "radius" );
00573                 
00574 
00575 
00576 
00577 
00578                 
00579                 if( nMatch( "VOLUME" , chCap ) )
00580                 {
00581                         strcpy( optimize.chTempWeight[optimize.nTempObs] , "volume" );
00582                 }
00583 
00584                 
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                 
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 }