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 }