00001 
00002 
00003 
00004 #include "cddefines.h"
00005 #include "physconst.h"
00006 #include "optimize.h"
00007 #include "phycon.h"
00008 #include "rfield.h"
00009 #include "radius.h"
00010 #include "geometry.h"
00011 #include "iterations.h"
00012 #include "stopcalc.h"
00013 #include "input.h"
00014 #include "parse.h"
00015 
00016 void ParseStop(char *chCard)
00017 {
00018         bool lgEOL;
00019 
00020         long int i, 
00021           j;
00022 
00023         double a, 
00024           effcol, 
00025           tread;
00026 
00027         DEBUG_ENTRY( "ParseStop()" );
00028 
00029         
00030         i = 5;
00031         a = FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL);
00032 
00033         
00034         if( lgEOL && !nMatch(" OFF",chCard) )
00035         {
00036                 NoNumb(chCard);
00037         }
00038 
00039         if( nMatch("TEMP",chCard) )
00040         {
00041                 
00042                 if( lgEOL && nMatch(" OFF",chCard) )
00043                 {
00044                         
00045 
00046 
00047                         StopCalc.tend = -1.f;
00048                 }
00049                 else
00050                 {
00051                         
00052 
00053 
00054                         if( a <= 10. && !nMatch("LINE",chCard) )
00055                         {
00056                                 tread = pow(10.,a);
00057                         }
00058                         else
00059                         {
00060                                 tread = a;
00061                         }
00062 
00063                         
00064                         if( tread < phycon.TEMP_LIMIT_LOW )
00065                         {
00066                                 fprintf( ioQQQ, 
00067                                         " Temperatures below %.2e K not allowed. Reset to lowest value."
00068                                         "   I am doing this myself.\n" ,
00069                                         phycon.TEMP_LIMIT_LOW );
00070                                 
00071                                 tread = phycon.TEMP_LIMIT_LOW*1.01;
00072                         }
00073                         else if( tread > phycon.TEMP_LIMIT_HIGH )
00074                         {
00075                                 fprintf( ioQQQ, 
00076                                         " Temperatures is above %.2e K not allowed. Reset to highest value."
00077                                         "   I am doing this myself.\n" ,
00078                                         phycon.TEMP_LIMIT_HIGH);
00079                                 
00080                                 tread = phycon.TEMP_LIMIT_HIGH*0.99;
00081                         }
00082 
00083                         if( nMatch("EXCE",chCard) )
00084                         {
00085                                 
00086 
00087                                 StopCalc.T2High = (realnum)tread;
00088                         }
00089                         else
00090                         {
00091                                 
00092 
00093                                 StopCalc.tend = (realnum)tread;
00094                         }
00095                 }
00096         }
00097 
00098         
00099         else if( nMatch("OPTI",chCard) && nMatch("21CM",chCard) )
00100         {
00101                 
00102                 bool lgLOG = true;
00103                 if( nMatch("LINE",chCard) )
00104                 {
00105                         
00106                         lgLOG = false;
00107                 }
00108                 i = 4;
00109                 j = (long int)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL);
00110                 if( j!=21 )
00111                 {
00112                         fprintf( ioQQQ, " First number on STOP 21CM OPTICAL DEPTH command must be 21\n" );
00113                         cdEXIT(EXIT_FAILURE);
00114                 }
00115                 
00116                 a = (long int)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL);
00117 
00118                 
00119                 if( lgLOG )
00120                 {
00121                         StopCalc.tauend = (realnum)pow(10.,a);
00122                 }
00123                 else
00124                 {
00125                         StopCalc.tauend = (realnum)a;
00126                 }
00127                 
00128                 StopCalc.lgStop21cm = true;
00129         }
00130         
00131         else if( nMatch("OPTI",chCard) )
00132         {
00133                 
00134                 bool lgLOG = true;
00135                 if( nMatch("LINE",chCard) )
00136                 {
00137                         
00138                         lgLOG = false;
00139                 }
00140 
00141                 if( a > 37. )
00142                 {
00143                         fprintf( ioQQQ, " optical depth too big\n" );
00144                         cdEXIT(EXIT_FAILURE);
00145                 }
00146 
00147                 
00148                 if( lgLOG )
00149                 {
00150                         StopCalc.tauend = (realnum)pow(10.,a);
00151                 }
00152                 else
00153                 {
00154                         StopCalc.tauend = (realnum)a;
00155                 }
00156 
00157                 
00158                 StopCalc.taunu = (realnum)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL);
00159 
00160                 if( lgEOL )
00161                 {
00162                         if( nMatch("LYMA",chCard) )
00163                         {
00164                                 
00165                                 StopCalc.taunu = 1.;
00166                         }
00167                         else if( nMatch("BALM",chCard) )
00168                         {
00169                                 
00170                                 StopCalc.taunu = 0.25;
00171                         }
00172                         else
00173                         {
00174                                 fprintf( ioQQQ, " There must be a second number, the energy in Ryd.  Sorry.\n" );
00175                                 cdEXIT(EXIT_FAILURE);
00176                         }
00177                 }
00178 
00179                 else
00180                 {
00181                         
00182                         if( StopCalc.taunu < 0. )
00183                         {
00184                                 StopCalc.taunu = (realnum)pow((realnum)10.f,StopCalc.taunu);
00185                         }
00186 
00187                         
00188                         if( StopCalc.taunu < rfield.emm || StopCalc.taunu > rfield.egamry )
00189                         {
00190                                 fprintf( ioQQQ, " The energy must be in the range %10.2e to %10.2e.  It was %10.2e. Sorry.\n", 
00191                                   rfield.emm, rfield.egamry, StopCalc.taunu );
00192                                 cdEXIT(EXIT_FAILURE);
00193                         }
00194                 }
00195         }
00196 
00197         
00198         else if( nMatch(" AV ",chCard) )
00199         {
00200                 
00201                 if( a<=0. )
00202                 {
00203                         a = pow(10.,a);
00204                 }
00205                 
00206 
00207                 if( nMatch("EXTE" , chCard ) )
00208                 {
00209                         StopCalc.AV_extended = (realnum)a;
00210                 }
00211                 else
00212                 {
00213                         
00214                         StopCalc.AV_point = (realnum)a;
00215                 }
00216         }
00217 
00218         
00219         else if( nMatch("MOLE",chCard) && nMatch("DEPL",chCard) )
00220         {
00221                 if( a <= 0. )
00222                 {
00223                         StopCalc.StopDepleteFrac = (realnum)pow(10.,a);
00224                 }
00225                 else
00226                 {
00227                         StopCalc.StopDepleteFrac = (realnum)a;
00228                 }
00229         }
00230 
00231         
00232         else if( nMatch("VELO",chCard) )
00233         {
00234                 
00235                 StopCalc.StopVelocity = (realnum)(a*1e5);
00236         }
00237 
00238         
00239         else if( nMatch("MASS",chCard) )
00240         {
00241                 
00242 
00243 
00244                 StopCalc.xMass = (realnum)a;
00245                 
00246                 if( StopCalc.xMass == 0 )
00247                         StopCalc.xMass = SMALLFLOAT;
00248         }
00249 
00250         
00251 
00252         else if( nMatch("THIC",chCard) || nMatch("DEPT",chCard) )
00253         {
00254                 
00255 
00256                 if( nMatch("LINE",chCard) )
00257                 {
00258                         radius.router[0] = a;
00259                 }
00260                 else
00261                 {
00262                         
00263                         if( a > 37. )
00264                         {
00265                                 fprintf( ioQQQ, " thickness too large\n" );
00266                                 cdEXIT(EXIT_FAILURE);
00267                         }
00268                         radius.router[0] = pow(10.,a);
00269                 }
00270 
00271                 
00272                 if( nMatch("PARS",chCard) )
00273                 {
00274                         radius.router[0] *= PARSEC;
00275                 }
00276 
00277                 
00278                 for( j=1; j < iterations.iter_malloc; j++ )
00279                 {
00280                         a = FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL);
00281                         if( lgEOL )
00282                         {
00283                                 radius.router[j] = radius.router[j-1];
00284                         }
00285                         else
00286                         {
00287                                 if( nMatch("LINE",chCard) )
00288                                 {
00289                                         radius.router[j] = a;
00290                                 }
00291                                 else
00292                                 {
00293                                         if( a > 37. )
00294                                         {
00295                                                 fprintf( ioQQQ, " thickness too large\n" );
00296                                                 cdEXIT(EXIT_FAILURE);
00297                                         }
00298                                         radius.router[j] = pow(10.,a);
00299                                 }
00300                                 if( nMatch("PARS",chCard) )
00301                                 {
00302                                         radius.router[j] *= PARSEC;
00303                                 }
00304                         }
00305                 }
00306 
00307                 
00308                 if( optimize.lgVarOn )
00309                 {
00310                         optimize.nvarxt[optimize.nparm] = 1;
00311                         strcpy( optimize.chVarFmt[optimize.nparm], "STOP THICKNESS %f" );
00312 
00313                         
00314                         optimize.nvfpnt[optimize.nparm] = input.nRead;
00315 
00316                         
00317                         optimize.vparm[0][optimize.nparm] = (realnum)log10(radius.router[0]);
00318                         optimize.vincr[optimize.nparm] = 0.5;
00319 
00320                         ++optimize.nparm;
00321                 }
00322         }
00323 
00324         
00325         else if( nMatch("ZONE",chCard) )
00326         {
00327                 
00328                 
00329 
00330                 geometry.nend[0] = (long)MAX2(1.,a);
00331                 geometry.lgZoneSet = true;
00332 
00333                 
00334                 geometry.lgEndDflt = false;
00335 
00336                 for( j=1; j < iterations.iter_malloc; j++ )
00337                 {
00338                         geometry.nend[j] = (long)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL);
00339                         
00340 
00341                         if( lgEOL )
00342                         {
00343                                 geometry.nend[j] = geometry.nend[j-1];
00344                         }
00345                         else
00346                         {
00347                                 
00348 
00349                                 geometry.nend[j] = MAX2( 1 , geometry.nend[j] );
00350                         }
00351                 }
00352         }
00353 
00354         
00355         else if( nMatch("EFRA",chCard) )
00356         {
00357                 if( a <= 0. )
00358                 {
00359                         StopCalc.StopElecFrac = (realnum)pow(10.,a);
00360                 }
00361                 else
00362                 {
00363                         StopCalc.StopElecFrac = (realnum)a;
00364                 }
00365         }
00366 
00367         
00368 
00369         else if( nMatch("MFRA",chCard) )
00370         {
00371                 if( a <= 0. )
00372                 {
00373                         StopCalc.StopH2MoleFrac = (realnum)pow(10.,a);
00374                 }
00375                 else
00376                 {
00377                         StopCalc.StopH2MoleFrac = (realnum)a;
00378                 }
00379         }
00380 
00381         
00382 
00383         else if( nMatch("PFRA",chCard) )
00384         {
00385                 if( a <= 0. )
00386                 {
00387                         StopCalc.StopHPlusFrac = (realnum)pow(10.,a);
00388                 }
00389                 else
00390                 {
00391                         StopCalc.StopHPlusFrac = (realnum)a;
00392                 }
00393         }
00394 
00395         
00396         else if( nMatch("COLU",chCard) )
00397         {
00398                 
00399 
00400                 if( nMatch( "LINE" , chCard ) )
00401                         a = log10(a);
00402 
00403                 
00404                 if( nMatch("EFFE",chCard) )
00405                 {
00406                         
00407                         effcol = pow(10.,a);
00408                         StopCalc.tauend = (realnum)(effcol*2.14e-22);
00409                         StopCalc.taunu = 73.5;
00410                         
00411                         if( optimize.lgVarOn )
00412                         {
00413                                 optimize.nvarxt[optimize.nparm] = 1;
00414                                 strcpy( optimize.chVarFmt[optimize.nparm], "STOP EFFECTIVE COLUMN DENSITY %f" );
00415                                 
00416                                 optimize.nvfpnt[optimize.nparm] = input.nRead;
00417                                 
00418                                 optimize.vparm[0][optimize.nparm] = (realnum)log10(effcol);
00419                                 optimize.vincr[optimize.nparm] = 0.5;
00420                                 ++optimize.nparm;
00421                         }
00422                 }
00423 
00424                 else if( nMatch("IONI",chCard) )
00425                 {
00426                         
00427                         if( a > 37. )
00428                         {
00429                                 fprintf( ioQQQ, " column too big\n" );
00430                                 cdEXIT(EXIT_FAILURE);
00431                         }
00432 
00433                         StopCalc.colpls = (realnum)pow(10.,a);
00434 
00435                         
00436                         if( optimize.lgVarOn )
00437                         {
00438                                 optimize.nvarxt[optimize.nparm] = 1;
00439                                 strcpy( optimize.chVarFmt[optimize.nparm], "STOP IONIZED COLUMN DENSITY %f" );
00440                                 
00441                                 optimize.nvfpnt[optimize.nparm] = input.nRead;
00442                                 
00443                                 optimize.vparm[0][optimize.nparm] = (realnum)log10(StopCalc.colpls);
00444                                 optimize.vincr[optimize.nparm] = 0.5;
00445                                 ++optimize.nparm;
00446                         }
00447                 }
00448 
00449                 
00450                 else if( nMatch("NEUT",chCard) )
00451                 {
00452                         StopCalc.colnut = (realnum)pow(10.,a);
00453 
00454                         
00455                         if( optimize.lgVarOn )
00456                         {
00457                                 optimize.nvarxt[optimize.nparm] = 1;
00458                                 strcpy( optimize.chVarFmt[optimize.nparm], "STOP NEUTRAL COLUMN DENSITY %f");
00459                                 
00460                                 optimize.nvfpnt[optimize.nparm] = input.nRead;
00461                                 
00462                                 optimize.vparm[0][optimize.nparm] = (realnum)log10(StopCalc.colnut);
00463                                 optimize.vincr[optimize.nparm] = 0.5;
00464                                 ++optimize.nparm;
00465                         }
00466                 }
00467 
00468                 
00469 
00470 
00471                 else if( nMatch(" H2 ",chCard) )
00472                 {
00473                         
00474 
00475 
00476                         i = 5;
00477                         j = (long int)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL);
00478                         if( j != 2 )
00479                         {
00480                                 fprintf( ioQQQ, " Something is wrong with the order of the numbers on this line.\n" );
00481                                 fprintf( ioQQQ, " The first number I encounter should be the 2 in H2.\n Sorry.\n" );
00482                                 cdEXIT(EXIT_FAILURE);
00483                         }
00484                         a = FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL);
00485                         StopCalc.col_h2 = (realnum)pow(10.,a);
00486 
00487                         
00488                         if( optimize.lgVarOn )
00489                         {
00490                                 optimize.nvarxt[optimize.nparm] = 1;
00491                                 strcpy( optimize.chVarFmt[optimize.nparm], "STOP H2 COLUMN DENSITY %f");
00492                                 
00493                                 optimize.nvfpnt[optimize.nparm] = input.nRead;
00494                                 
00495                                 optimize.vparm[0][optimize.nparm] = (realnum)log10(StopCalc.col_h2);
00496                                 optimize.vincr[optimize.nparm] = 0.5;
00497                                 ++optimize.nparm;
00498                         }
00499                 }
00500 
00501                 else if( nMatch("ATOM",chCard) )
00502                 {
00503                         StopCalc.col_h2_nut = (realnum)pow(10.,a);
00504                         
00505                         if( optimize.lgVarOn )
00506                         {
00507                                 optimize.nvarxt[optimize.nparm] = 1;
00508                                 strcpy( optimize.chVarFmt[optimize.nparm], "STOP ATOMIC COLUMN DENSITY %f");
00509                                 
00510                                 optimize.nvfpnt[optimize.nparm] = input.nRead;
00511                                 
00512                                 optimize.vparm[0][optimize.nparm] = (realnum)log10(StopCalc.col_h2_nut);
00513                                 optimize.vincr[optimize.nparm] = 0.5;
00514                                 ++optimize.nparm;
00515                         }
00516                 }
00517 
00518                 else if( nMatch("H/TS",chCard) )
00519                 {
00520                         
00521                         StopCalc.col_H0_ov_Tspin = (realnum)pow(10.,a);
00522                         
00523                         if( optimize.lgVarOn )
00524                         {
00525                                 optimize.nvarxt[optimize.nparm] = 1;
00526                                 strcpy( optimize.chVarFmt[optimize.nparm], "STOP H/TSPIN COLUMN DENSITY %f");
00527                                 
00528                                 optimize.nvfpnt[optimize.nparm] = input.nRead;
00529                                 
00530                                 optimize.vparm[0][optimize.nparm] = (realnum)log10(StopCalc.col_H0_ov_Tspin);
00531                                 optimize.vincr[optimize.nparm] = 0.5;
00532                                 ++optimize.nparm;
00533                         }
00534                 }
00535 
00536                 else if( nMatch(" CO ",chCard) )
00537                 {
00538                         
00539                         
00540                         StopCalc.col_monoxco = (realnum)pow(10.,a);
00541                         
00542                         if( optimize.lgVarOn )
00543                         {
00544                                 optimize.nvarxt[optimize.nparm] = 1;
00545                                 strcpy( optimize.chVarFmt[optimize.nparm], "STOP CO COLUMN DENSITY %f");
00546                                 
00547                                 optimize.nvfpnt[optimize.nparm] = input.nRead;
00548                                 
00549                                 optimize.vparm[0][optimize.nparm] = (realnum)log10(StopCalc.col_monoxco);
00550                                 optimize.vincr[optimize.nparm] = 0.5;
00551                                 ++optimize.nparm;
00552                         }
00553                 }
00554 
00555                 
00556                 else
00557                 {
00558                         
00559                         if( a > 37. )
00560                         {
00561                                 fprintf( ioQQQ, " column too big\n" );
00562                                 cdEXIT(EXIT_FAILURE);
00563                         }
00564 
00565                         StopCalc.HColStop = (realnum)pow(10.,a);
00566 
00567                         
00568                         if( optimize.lgVarOn )
00569                         {
00570                                 optimize.nvarxt[optimize.nparm] = 1;
00571                                 strcpy( optimize.chVarFmt[optimize.nparm], "STOP COLUMN DENSITY %f" );
00572                                 
00573                                 optimize.nvfpnt[optimize.nparm] = input.nRead;
00574                                 
00575                                 optimize.vparm[0][optimize.nparm] = (realnum)log10(StopCalc.HColStop);
00576                                 optimize.vincr[optimize.nparm] = 0.5;
00577                                 ++optimize.nparm;
00578                         }
00579                 }
00580         }
00581 
00582         
00583         else if( nMatch("EDEN",chCard) )
00584         {
00585                 
00586 
00587                 if( nMatch("LINE",chCard) )
00588                 {
00589                         StopCalc.StopElecDensity = (realnum)a;
00590                 }
00591                 else
00592                 {
00593                         StopCalc.StopElecDensity = (realnum)pow(10.,a);
00594                 }
00595         }
00596 
00597         
00598 
00599         else if( nMatch("LINE",chCard) )
00600         {
00601                 char chLabel[5];
00602                 
00603 
00604 
00605                 
00606 
00607                 GetQuote( chLabel , chCard , true );
00608 
00609                 
00610                 strncpy( StopCalc.chStopLabel1[StopCalc.nstpl], chLabel , 4 );
00611                 StopCalc.chStopLabel1[StopCalc.nstpl][4] = 0;
00612 
00613                 i = 5;
00614                 
00615                 StopCalc.StopLineWl1[StopCalc.nstpl] = 
00616                         (realnum)FFmtRead(chCard,&i,INPUT_LINE_LENGTH, &lgEOL);
00617 
00618                 
00619                 if( input.chCARDCAPS[i-1] == 'M' )
00620                 {
00621                         
00622                         StopCalc.StopLineWl1[StopCalc.nstpl] *= 1e4;
00623                 }
00624                 else if( input.chCARDCAPS[i-1] == 'C' )
00625                 {
00626                         
00627                         StopCalc.StopLineWl1[StopCalc.nstpl] *= 1e8;
00628                 }
00629 
00630                 
00631                 StopCalc.stpint[StopCalc.nstpl] = 
00632                         (realnum)FFmtRead(chCard,&i,INPUT_LINE_LENGTH, &lgEOL);
00633                 if( lgEOL )
00634                 {
00635                         fprintf( ioQQQ, " There MUST be a relative intensity  entered "
00636                                 "for first line in STOP LINE command.  Sorry.\n" );
00637                         cdEXIT(EXIT_FAILURE);
00638                 }
00639 
00640                 
00641                 j = i;
00642                 a = FFmtRead(chCard,&j,INPUT_LINE_LENGTH, &lgEOL);
00643 
00644                 if( lgEOL )
00645                 {
00646                         
00647                         strncpy( StopCalc.chStopLabel2[StopCalc.nstpl], "TOTL" , 4 );
00648                         StopCalc.chStopLabel2[StopCalc.nstpl][4] = 0;
00649                         StopCalc.StopLineWl2[StopCalc.nstpl] = 4861.f;
00650                 }
00651                 else
00652                 {
00653                         
00654 
00655                         GetQuote( chLabel , chCard , true );
00656                         
00657                         strncpy( StopCalc.chStopLabel2[StopCalc.nstpl], chLabel , 4 );
00658                         StopCalc.chStopLabel2[StopCalc.nstpl][4] = 0;
00659 
00660                         
00661 
00662                         StopCalc.StopLineWl2[StopCalc.nstpl] = 
00663                                 (realnum)FFmtRead(chCard,&i, INPUT_LINE_LENGTH,&lgEOL);
00664 
00665                         
00666                         if( input.chCARDCAPS[i-1] == 'M' )
00667                         {
00668                                 
00669                                 StopCalc.StopLineWl2[StopCalc.nstpl] *= 1e4;
00670                         }
00671                         else if( input.chCARDCAPS[i-1] == 'C' )
00672                         {
00673                                 
00674                                 StopCalc.StopLineWl2[StopCalc.nstpl] *= 1e8;
00675                         }
00676                 }
00677                 
00678                 StopCalc.nstpl = MIN2(StopCalc.nstpl+1,MXSTPL-1);
00679         }
00680 
00681         else if( nMatch("NTOT" , chCard ) && nMatch("ALIO" , chCard ) )
00682         {
00683                 
00684 
00685 
00686                 StopCalc.nTotalIonizStop = (long)a;
00687         }
00688 
00689         
00690         else
00691         {
00692                 fprintf( ioQQQ, " I did not recognize a keyword on this STOP line, line image follows;\n" );
00693                 fprintf( ioQQQ, " \"%s\"\n Sorry.\n" , chCard);
00694                 cdEXIT(EXIT_FAILURE);
00695         }
00696         return;
00697 }