00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #include <stdio.h>
00046 #include <math.h>
00047 #include <string.h>
00048 #include <stdlib.h>
00049 #include "libcpixe.h"
00050 #include "stop96.h"
00051 #include "compilopt.h"
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 int readINPUT(const char *InputFileNm, EXP_PARAM *pexppar, EXTRAINFO *pExtraInfo)
00078 {
00079 FILE *f;
00080 int i;
00081 char *command,*arg;
00082 char line[LONGSTRINGLENGTH]="";
00083 int flag[16];
00084
00085
00086
00087 for(i=0;i<16;i++)flag[i]=0;
00088 pExtraInfo->WantOutputfile=0;
00089 pExtraInfo->DoCalibration=0;
00090
00091 pexppar->simpar.AllowSXFCorr=0;flag[10]=-1;
00092 pexppar->simpar.AllowXEqCalc=0; flag[11]=-1;
00093
00094 f = fopen(InputFileNm, "r");
00095 if (f == NULL)
00096 {fprintf(stderr,"\nERROR: Could not open file '%s' for read.\n",InputFileNm);exit(1);}
00097
00098
00099 for(;!feof(f) && strcasecmp(line, "BEGIN_INPUT");){
00100 fscanf(f,"%255s",line);
00101 flag[0]=1;
00102 }
00103
00104 for(;!feof(f);){
00105
00106 fgets(line,sizeof(line),f);
00107
00108
00109
00110 command = strtok( line, "\n\t \r" ) ;
00111 if( command != NULL && command[0] != '#' ){
00112
00113
00114
00115
00116 if(!strcmp(command,"END_INPUT")){
00117 flag[1]=1;
00118 break;
00119 }
00120 else if(!strcmp(command,"ION")){
00121
00122
00123
00124 arg=strtok( NULL,"\n\t \r");
00125 strncpy(pexppar->ion.symbol,arg,3);
00126
00127 if (strncasecmp(pexppar->ion.symbol,"H",3))
00128 {fprintf(stderr,"\nERROR: Currently, only H ions are supported\n");exit(1);}
00129 pexppar->ion.Z=symbol2Z(pexppar->ion.symbol);
00130 pexppar->ion.A=Z2mass(pexppar->ion.Z, &pexppar->ion.IM,'m');
00131 Z2mass(pexppar->ion.Z, &pexppar->ion.M,'n');
00132 flag[2]=1;
00133
00134 }
00135 else if(!strcmp(command,"IONMASS")){
00136
00137
00138
00139 arg=strtok( NULL,"\n\t \r");
00140 pexppar->ion.M=atof(arg);
00141
00142 }
00143 else if(!strcmp(command,"KEV")){
00144
00145
00146
00147 arg=strtok( NULL,"\n\t \r");
00148 pexppar->BeamEner=atof(arg);
00149 flag[3]=1;
00150 }
00151 else if(!strcmp(command,"INCANG")){
00152
00153
00154
00155 arg=strtok( NULL,"\n\t \r");
00156 pexppar->IncAng=atof(arg);
00157 pexppar->IncAng *= DEG2RAD;
00158 pexppar->cosInc = cos(pexppar->IncAng);
00159 flag[4]=1;
00160 }
00161 else if(!strcmp(command,"EXITANG")){
00162
00163
00164
00165 arg=strtok( NULL,"\n\t \r");
00166 pexppar->DetAng=atof(arg);
00167 pexppar->DetAng *= DEG2RAD;
00168 pexppar->cosDet = cos(pexppar->DetAng);
00169 flag[5]=1;
00170 }
00171 else if(!strcmp(command,"BEAMCOL")){
00172
00173
00174
00175 arg=strtok( NULL,"\n\t \r");
00176 pexppar->BeamCol=atof(arg);
00177 pexppar->BeamCross = M_PI * (pexppar->BeamCol*pexppar->BeamCol) / 400;
00178 flag[6]=1;
00179 }
00180 else if(!strcmp(command,"DETCOLFAC")){
00181
00182
00183 arg=strtok( NULL,"\n\t \r");
00184 pexppar->DetColFac=atof(arg);
00185
00186 flag[7]=1;
00187 }
00188 else if(!strcmp(command,"CHARGE")){
00189
00190
00191 arg=strtok( NULL,"\n\t \r");
00192 pexppar->simpar.ColCharge=atof(arg);
00193
00194 flag[8]=1;
00195 }
00196 else if(!strcmp(command,"LIVETIME")){
00197
00198
00199 arg=strtok( NULL,"\n\t \r");
00200 pexppar->simpar.DTCC=atof(arg);
00201
00202 flag[9]=1;
00203 }
00204 else if(!strcmp(command,"ALLOWSXFCORR")){
00205
00206
00207 arg=strtok( NULL,"\n\t \r");
00208 pexppar->simpar.AllowSXFCorr=atoi(arg);
00209
00210 flag[10]=1;
00211 }
00212 else if(!strcmp(command,"ALLOWXEQCALC")){
00213
00214
00215 arg=strtok( NULL,"\n\t \r");
00216 pexppar->simpar.AllowXEqCalc=atoi(arg);
00217
00218 flag[11]=1;
00219 }
00220 else if(!strcmp(command,"CALIBFILE")){
00221
00222
00223
00224 arg=strtok( NULL,"\n\t \r");
00225 strncpy(pExtraInfo->XYldFileNm,arg,LONGSTRINGLENGTH);
00226
00227 flag[12]=1;
00228 pExtraInfo->DoCalibration=0;
00229 }
00230 else if(!strcmp(command,"DOCALIBRATION")){
00231
00232
00233
00234 arg=strtok( NULL,"\n\t \r");
00235 pExtraInfo->DoCalibration=atoi(arg);
00236
00237 flag[12]=1;
00238 }
00239 else if(!strcmp(command,"SAMPLEFILE")){
00240
00241
00242
00243
00244 arg=strtok( NULL,"\n\t \r");
00245 strncpy(pExtraInfo->SampleFileNm,arg,LONGSTRINGLENGTH);
00246 flag[13]=1;
00247 }
00248 else if(!strcmp(command,"FILTERFILE")){
00249
00250
00251
00252
00253 arg=strtok( NULL,"\n\t \r");
00254 strncpy(pExtraInfo->FilterFileNm,arg,LONGSTRINGLENGTH);
00255 flag[14]=1;
00256 }
00257 else if(!strcmp(command,"CFLAGSFILE")){
00258
00259
00260
00261
00262 arg=strtok( NULL,"\n\t \r");
00263 strncpy(pExtraInfo->AreasFileNm,arg,LONGSTRINGLENGTH);
00264 pExtraInfo->AreasFormat=1;
00265 flag[15]=1;
00266 }
00267 else if(!strcmp(command,"DTAREASFILE")){
00268
00269
00270
00271
00272 arg=strtok( NULL,"\n\t \r");
00273 strncpy(pExtraInfo->AreasFileNm,arg,LONGSTRINGLENGTH);
00274 pExtraInfo->AreasFormat=2;
00275 flag[15]=1;
00276 }
00277 else if(!strcmp(command,"DBPATH")){
00278
00279
00280
00281
00282 arg=strtok( NULL,"\n\t \r");
00283 strncpy(pExtraInfo->DBpath,arg,LONGSTRINGLENGTH);
00284 }
00285 else if(!strcmp(command,"OUTPUTFILE")){
00286
00287
00288
00289
00290 arg=strtok( NULL,"\n\t \r");
00291 strncpy(pExtraInfo->OutputFileNm,arg,LONGSTRINGLENGTH);
00292 pExtraInfo->WantOutputfile=1;
00293
00294 }
00295
00296 else {
00297 fprintf(stderr,"\n ERROR:ReadInput: command '%s' not known. Press <INTRO> to continue ...***\n",command);
00298 getchar();
00299 }
00300 }
00301 }
00302
00303
00304 fclose(f);
00305
00306
00307 for(i=0;i<16;i++)if(flag[i]==0){fprintf(stderr,"\n ERROR:ReadInput: Missing command in inputfile (#%i)\n",i);exit(1);}
00308
00309 pexppar->cosFac = pexppar->cosInc / pexppar->cosDet;
00310
00311 pexppar->FinalEner = 0.1 * pexppar->BeamEner;
00312 if(pexppar->FinalEner>100.)pexppar->FinalEner = 100.;
00313
00314 return(0);
00315
00316 }
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336 int readEXP_PARAM(char *ExpParFileNm, EXP_PARAM *pexppar)
00337 {
00338
00339 FILE *ExpParFile;
00340
00341 ExpParFile = fopen(ExpParFileNm, "r");
00342 if (ExpParFile == NULL)
00343 {fprintf(stderr,"\nERROR: Could not open file '%s' for read.\n",ExpParFileNm);exit(1);}
00344
00345
00346 strncpy(pexppar->ion.symbol,"H",2);
00347 pexppar->ion.Z=symbol2Z(pexppar->ion.symbol);
00348 pexppar->ion.A=Z2mass(pexppar->ion.Z, &pexppar->ion.IM,'m');
00349 Z2mass(pexppar->ion.Z, &pexppar->ion.M,'n');
00350
00351 fscanf(ExpParFile, "%lg", &pexppar->BeamEner);
00352 fscanf(ExpParFile, "%lg", &pexppar->BeamCol);
00353 fscanf(ExpParFile, "%lg", &pexppar->DetColFac);
00354 fscanf(ExpParFile, "%lg", &pexppar->IncAng);
00355 fscanf(ExpParFile, "%lg", &pexppar->DetAng);
00356
00357 fclose(ExpParFile);
00358
00359 pexppar->IncAng *= DEG2RAD;
00360 pexppar->cosInc = cos(pexppar->IncAng);
00361 pexppar->DetAng *= DEG2RAD;
00362 pexppar->cosDet = cos(pexppar->DetAng);
00363 pexppar->BeamCross = M_PI * (pexppar->BeamCol*pexppar->BeamCol) / 400;
00364
00365
00366 pexppar->cosFac = pexppar->cosInc / pexppar->cosDet;
00367
00368 pexppar->FinalEner = 0.1 * pexppar->BeamEner;
00369 if(pexppar->FinalEner>100.)pexppar->FinalEner = 100.;
00370
00371
00372 return(0);
00373 }
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394 int readSIM_PARAM(char *SampleParamFileNm, SIM_PARAM *simpar,char *IniMatFileNm, char *FilterFileNm, char *XYldFileNm)
00395 {
00396
00397 FILE *SampleParamFile;
00398 char AbsType[6];
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410 SampleParamFile = fopen(SampleParamFileNm, "r");
00411 if (SampleParamFile == NULL)
00412 {fprintf(stderr,"\nERROR: Could not open file '%s' for read.\n",SampleParamFileNm);exit(1);}
00413
00414
00415 fscanf(SampleParamFile,"%255s",IniMatFileNm);
00416 fscanf(SampleParamFile,"%255s",FilterFileNm);
00417 fscanf(SampleParamFile,"%255s",XYldFileNm);
00418 fscanf(SampleParamFile, "%5s", AbsType);
00419 fscanf(SampleParamFile, "%d", &simpar->AllowSXFCorr);
00420 fscanf(SampleParamFile, "%d", &simpar->AllowXEqCalc);
00421 fscanf(SampleParamFile, "%lg", &simpar->DTCC);
00422
00423
00424
00425
00426 fscanf(SampleParamFile, "%lg", &simpar->ColCharge);
00427
00428 fclose(SampleParamFile);
00429
00430
00431 if (strcasecmp(AbsType, "NoAbs")) {
00432 simpar->useFilter=1;
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453 }else {
00454
00455 simpar->useFilter=0;
00456 }
00457 return(0);
00458 }
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469 int symbol2Z(char *symbol){
00470 int Z;
00471
00472 ChemSymb chsymbols[110] = {
00473 "--", "H" , "He", "Li", "Be", "B" , "C" , "N" , "O" , "F" , "Ne", "Na",
00474 "Mg", "Al", "Si", "P" , "S" , "Cl", "Ar", "K" , "Ca", "Sc", "Ti", "V" ,
00475 "Cr", "Mn", "Fe", "Co", "Ni", "Cu", "Zn", "Ga", "Ge", "As", "Se", "Br",
00476 "Kr", "Rb", "Sr", "Y" , "Zr", "Nb", "Mo", "Tc", "Ru", "Rh", "Pd", "Ag",
00477 "Cd", "In", "Sn", "Sb", "Te", "I" , "Xe", "Cs", "Ba", "La", "Ce", "Pr",
00478 "Nd", "Pm", "Sm", "Eu", "Gd", "Tb", "Dy", "Ho", "Er", "Tm", "Yb", "Lu",
00479 "Hf", "Ta", "W" , "Re", "Os", "Ir", "Pt", "Au", "Hg", "Tl", "Pb", "Bi",
00480 "Po", "At", "Rn", "Fr", "Ra", "Ac", "Th", "Pa", "U" , "Np", "Pu", "Am",
00481 "Cm", "Bk", "Cf", "Es", "Fm", "Md", "No", "Lr", "Rf", "Db", "Sg", "Bh",
00482 "Hs", "Mt"
00483 };
00484 for(Z=1;strncasecmp(symbol,chsymbols[Z],3) && Z<=99;Z++);
00485 if(Z<1 || Z> 109) {fprintf(stderr,"\nERROR: Chemical Symbol '%s' not known.\n",symbol);exit(1);}
00486 else return(Z);
00487 }
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500 int Z2mass(int Z, double *mass, char option)
00501 {
00502
00503 int maiAArray[93]={
00504 0 , 1 , 4 , 7 , 9 , 11 , 12 , 14 ,
00505 16 , 19 , 20 , 23 , 24 , 27 , 28 , 31 ,
00506 32 , 35 , 40 , 39 , 40 , 45 , 48 , 51 ,
00507 52 , 55 , 56 , 59 , 58 , 63 , 64 , 69 ,
00508 74 , 75 , 80 , 79 , 84 , 85 , 88 , 89 ,
00509 90 , 93 , 98 , 97 , 102 , 103 , 106 , 107 ,
00510 114 , 115 , 120 , 121 , 130 , 127 , 132 , 133 ,
00511 138 , 139 , 140 , 141 , 142 , 148 , 152 , 153 ,
00512 158 , 159 , 164 , 165 , 166 , 169 , 174 , 175 ,
00513 180 , 181 , 184 , 187 , 192 , 193 , 195 , 197 ,
00514 202 , 205 , 208 , 209 , 209 , 210 , 222 , 223 ,
00515 226 , 227 , 232 , 231 , 238};
00516
00517 double maiMArray[93]={
00518 0.000 , 1.008 , 4.003 , 7.016 , 9.012 , 11.009 , 12.000 , 14.003 ,
00519 15.995 , 18.998 , 19.992 , 22.990 , 23.985 , 26.982 , 27.977 , 30.974 ,
00520 31.972 , 34.969 , 39.962 , 38.964 , 39.963 , 44.956 , 47.950 , 50.940 ,
00521 51.940 , 54.940 , 55.935 , 58.930 , 57.940 , 62.930 , 63.930 , 68.930 ,
00522 73.920 , 74.920 , 79.920 , 78.920 , 83.912 , 84.910 , 87.910 , 88.906 ,
00523 89.900 , 92.910 , 97.905 , 97.000 , 101.900 , 102.900 , 105.900 , 106.900 ,
00524 113.900 , 114.900 , 119.900 , 120.900 , 129.906 , 126.900 , 131.904 , 132.905 ,
00525 137.905 , 139.000 , 140.000 , 141.000 , 142.000 , 148.000 , 152.000 , 153.000 ,
00526 157.900 , 158.925 , 164.000 , 165.000 , 166.000 , 169.000 , 174.000 , 175.000 ,
00527 180.000 , 181.000 , 184.000 , 187.000 , 192.000 , 193.000 , 195.000 , 197.000 ,
00528 202.000 , 205.000 , 208.000 , 209.000 , 208.982 , 210.000 , 222.000 , 223.000 ,
00529 226.000 , 227.000 , 232.000 , 231.000 , 238.040 };
00530
00531 double natMArray[93]={
00532 0.000 , 1.008 , 4.003 , 6.941 , 9.012 , 10.811 , 12.011 , 14.007 ,
00533 15.999 , 18.998 , 20.180 , 22.990 , 24.305 , 26.982 , 28.086 , 30.974 ,
00534 32.066 , 35.453 , 39.948 , 39.098 , 40.080 , 44.956 , 47.900 , 50.942 ,
00535 51.996 , 54.938 , 55.847 , 58.933 , 58.690 , 63.546 , 65.390 , 69.720 ,
00536 72.610 , 74.922 , 78.960 , 79.904 , 83.800 , 85.470 , 87.620 , 88.905 ,
00537 91.220 , 92.906 , 95.940 , 97.000 , 101.070 , 102.910 , 106.400 , 107.870 ,
00538 112.400 , 114.820 , 118.710 , 121.750 , 127.600 , 126.900 , 131.300 , 132.910 ,
00539 137.327 , 138.910 , 140.120 , 140.910 , 144.240 , 148.000 , 150.360 , 151.970 ,
00540 157.250 , 158.930 , 162.500 , 164.930 , 167.260 , 168.930 , 173.040 , 174.970 ,
00541 178.490 , 180.950 , 183.850 , 186.200 , 190.200 , 192.200 , 195.080 , 196.970 ,
00542 200.590 , 204.380 , 207.190 , 208.980 , 210.000 , 210.000 , 222.000 , 223.000 ,
00543 226.000 , 227.000 , 232.000 , 231.000 , 238.030 };
00544
00545 if(Z<1 || Z> 92) {fprintf(stderr,"\nERROR: Data for Atomic number '%d' not available.\n",Z);exit(1);}
00546
00547 switch(option){
00548 case 'n':
00549 *mass=natMArray[Z];
00550 break;
00551 case 'm':
00552 *mass=maiMArray[Z];
00553 break;
00554 default:
00555 {fprintf(stderr,"\nERROR: Z2mass() Option argument can only be 'n' (natural) or 'm' (most abundant) \n");exit(1);}
00556 break;
00557 }
00558
00559 return(maiAArray[Z]);
00560 }
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577 int readCOMPOUND(FILE *f, int nelem, COMPOUND *c)
00578 {
00579 int i,nchar1,nchar2,maxZ;
00580 double sumM;
00581 char temp[30],temp2[30];
00582
00583
00584 if(nelem<1){fprintf(stderr,"\n ERROR: readCOMPOUND must read at least 1 element\n");exit(1);}
00585 else{
00586 c->nelem=nelem;
00587 if(!(c->elem=(ELEMENT*)calloc(nelem,sizeof(ELEMENT)))){fprintf(stderr,"\n Error allocating memory\n");exit(1);}
00588 if(!(c->X=(double*)calloc(nelem,sizeof(double)))){fprintf(stderr,"\n Error allocating memory\n");exit(1);}
00589 if(!(c->xn=(double*)calloc(nelem,sizeof(double)))){fprintf(stderr,"\n Error allocating memory\n");exit(1);}
00590 if(!(c->w=(double*)calloc(nelem,sizeof(double)))){fprintf(stderr,"\n Error allocating memory\n");exit(1);}
00591 for(maxZ=0.,c->sumX=0.,sumM=0.,i=0,nchar1=0,nchar2=0 ; i<nelem ; i++){
00592 fscanf(f,"%2s%lf",(c->elem[i].symbol),&(c->X[i]));
00593 c->elem[i].Z=symbol2Z(c->elem[i].symbol);
00594 c->elem[i].A=Z2mass(c->elem[i].Z, &c->elem[i].IM, 'm');
00595 Z2mass(c->elem[i].Z, &c->elem[i].M, 'n');
00596
00597
00598 if(c->elem[i].Z==0){fprintf(stderr,"\n ERROR: Chemical symbol '%s' not valid\n",c->elem[i].symbol);exit(1);}
00599 c->sumX+=c->X[i];
00600 sumM+=c->elem[i].M*c->X[i];
00601 if(c->elem[i].Z>maxZ)maxZ=c->elem[i].Z;
00602 nchar1+=strlen(c->elem[i].symbol);
00603 nchar2+=snprintf(temp,30,"%4lf",c->X[i]);
00604 }
00605
00606 for(i=0;i<nelem;i++){
00607 c->xn[i]=c->X[i]/c->sumX;
00608 c->w[i]=c->X[i]*c->elem[i].M/sumM;
00609 }
00610
00611 strcpy(temp2,"");
00612 strcpy(temp,"");
00613 if(nchar1+nchar2 < 30 && nelem<4){
00614 for(i=0;i<nelem;i++){
00615 if(c->X[i]!=1.)snprintf(temp,30,"%s%1.lf",c->elem[i].symbol,c->X[i]);
00616 else snprintf(temp,30,"%s",c->elem[i].symbol);
00617 strcat(temp2,temp);
00618 }
00619 }
00620 else if(nchar1<30){
00621 for(i=0;i<nelem;i++){
00622 snprintf(temp,30,"%s",c->elem[i].symbol);
00623 strcat(temp2,temp);
00624 }
00625 }
00626 else{
00627 for(i=0;i<nelem;i++){
00628 snprintf(temp2,25,"%s%s",temp,c->elem[i].symbol);
00629 strcpy(temp,temp2);
00630 }
00631 snprintf(temp2,30,"%s+",temp);
00632 }
00633 strcpy(c->name,temp2);
00634 }
00635 return(maxZ);
00636 }
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667 int readsample(char *SampleDefFileNm, int *MaxZ, int *NFoil, foil **Sample)
00668 {
00669
00670 FILE *SampleDefFile;
00671 char dummy[LONGSTRINGLENGTH];
00672 int i,tempZ,j;
00673 foil *pfoil;
00674 double ug2at,natmass;
00675 SampleDefFile = fopen(SampleDefFileNm, "r");
00676 if (SampleDefFile == NULL)
00677 {fprintf(stderr,"\nERROR: Could not open file '%s' for read.\n",SampleDefFileNm);exit(1);}
00678
00679
00680 do {
00681 fscanf(SampleDefFile,"%255s",dummy);
00682 } while (strcasecmp(dummy, "NUMBER_OF_FOILS"));
00683
00684 fscanf(SampleDefFile, "%d", NFoil);
00685
00686
00687
00688 *Sample=(foil*)malloc((*NFoil)*sizeof(foil));
00689 if (*Sample==NULL){fprintf(stderr,"\n Error allocating memory (Sample)\n");exit(1);}
00690
00691 for (*MaxZ=0,i = 0; i < *NFoil ; i++) {
00692 pfoil=&((*Sample)[i]);
00693 do {
00694 fscanf(SampleDefFile,"%255s",dummy);
00695 } while (strcasecmp(dummy, "FOIL"));
00696
00697 fscanf(SampleDefFile, "%lg %10s", &pfoil->thick, dummy);
00698 if(strcasecmp(dummy,"cm2") && strcasecmp(dummy,"mg")){
00699 fprintf(stderr,"\n Error: Bad syntax in sample definition file: '%s' is not a known thickness unit\n",dummy);exit(1);
00700 }
00701 fscanf(SampleDefFile, "%d", &pfoil->nfoilelm);
00702 tempZ=readCOMPOUND(SampleDefFile, pfoil->nfoilelm, &pfoil->comp);
00703 if(tempZ>*MaxZ) *MaxZ=tempZ;
00704
00705 if(!strcasecmp(dummy,"mg")){
00706
00707 for(natmass=0, j=0 ; j<pfoil->nfoilelm ; j++) natmass += pfoil->comp.xn[j] * pfoil->comp.elem[j].M;
00708 ug2at=natmass/602.2141;
00709
00710 pfoil->thick *= (1e3/ug2at);
00711
00712 }
00713
00714 }
00715 fclose(SampleDefFile);
00716
00717 return(0);
00718 }
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732 int createPresentElems(int MaxZ, int NFoil, const foil *MatArray, int **PresentElems)
00733 {
00734 const COMPOUND *pcmp;
00735 int tempZ;
00736 int i,j;
00737
00738
00739 *PresentElems=(int*)calloc((MaxZ+1),sizeof(int));
00740 if (*PresentElems==NULL){fprintf(stderr,"\n Error allocating memory (PresentElems)\n");exit(1);}
00741 for(i=0;i<NFoil; i++) {
00742 pcmp=&MatArray[i].comp;
00743 for(j=0 ; j< pcmp->nelem ; j++) {
00744 tempZ=pcmp->elem[j].Z;
00745 if(tempZ<=MaxZ) (*PresentElems)[tempZ]=1;
00746 else {fprintf(stderr,"\n ERROR: in createPresentElems(): %d > MaxZ (=%d)\n",tempZ,MaxZ);exit(1);}
00747 }
00748 }
00749 return(0);
00750 }
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792 int readCalcFlags(const char *CalcFlagsFileNm, const int *PresentElems, int MaxZinsample, int AreasFormat, CPIXERESULTS **CalcFlags){
00793
00794 int i,j,tempZ,nread=0;
00795 char dummy[LONGSTRINGLENGTH];
00796 double trash;
00797 ChemSymb tempchem;
00798 CPIXERESULTS *pCFlags;
00799 FILE *CalcFlagsFile;
00800
00801 CalcFlagsFile = fopen(CalcFlagsFileNm, "r");
00802 if (CalcFlagsFile== NULL)
00803 {fprintf(stderr,"\nERROR: Could not open file '%s' for read.\n",CalcFlagsFileNm);exit(1);}
00804
00805
00806 *CalcFlags=(CPIXERESULTS*)calloc(MaxZinsample+1,sizeof(CPIXERESULTS));
00807 if (*CalcFlags==NULL){fprintf(stderr,"\n Error allocating memory (CalcFlags)\n");exit(1);}
00808
00809
00810 for(i=0;i<=MaxZinsample;i++)if(PresentElems[i])(*CalcFlags)[i].atnum=i;
00811
00812 do {
00813 fscanf(CalcFlagsFile,"%255s",dummy);
00814 if(feof(CalcFlagsFile)) {fprintf(stderr,"\nERROR: 'DATA' not found in '%s'\n",CalcFlagsFileNm);exit(1);}
00815 } while (strcasecmp(dummy, "DATA"));
00816
00817
00818 for(;!feof(CalcFlagsFile);){
00819 fscanf(CalcFlagsFile,"%255s",dummy);
00820
00821 if( (!strcmp(dummy,"END_DATA") && AreasFormat==1) || (AreasFormat==2 && !strcmp(dummy,"CALIB" )) ) {
00822 break;
00823 }
00824
00825
00826
00827
00828
00829
00830
00831
00832 if(AreasFormat==1){
00833 strncpy(tempchem,dummy,3);
00834 tempZ = symbol2Z(tempchem);
00835 }
00836 else if (AreasFormat==2){
00837 strncpy(tempchem,"-",3);
00838 tempZ = atoi(dummy);
00839 }
00840 else tempZ=0;
00841
00842 if(tempZ<=MaxZinsample && PresentElems[tempZ]){
00843 nread++;
00844
00845 pCFlags=&(*CalcFlags)[tempZ];
00846 pCFlags->atnum=tempZ;
00847
00848
00849 for(i=1;i<=3;i++) {
00850 fscanf(CalcFlagsFile, "%lg", &pCFlags->simareas.K_[i]);
00851 if(AreasFormat==2)fscanf(CalcFlagsFile, "%lg", &pCFlags->err.K_[i]);
00852 }
00853
00854 for(i=1;i<=3;i++){
00855 for(j=1;j<=3;j++){
00856 fscanf(CalcFlagsFile, "%lg", &pCFlags->simareas.L_[i][j]);
00857 if(AreasFormat==2)fscanf(CalcFlagsFile, "%lg", &pCFlags->err.L_[i][j]);
00858 }
00859 }
00860
00861 for(i=1;i<=3;i++) {
00862 fscanf(CalcFlagsFile, "%lg", &pCFlags->simareas.M_[i]);
00863 if(AreasFormat==2)fscanf(CalcFlagsFile, "%lg", &pCFlags->err.M_[i]);
00864 }
00865 #if CPIXEVERBOSITY > 0
00866 printf("\n CalcFlags[%2d] (%2s) read", pCFlags->atnum,tempchem);
00867 #endif
00868 }
00869 else {
00870 for(i=0;i<15;i++)fscanf(CalcFlagsFile, "%lg",&trash);
00871 if(AreasFormat==2)for(i=0;i<15;i++)fscanf(CalcFlagsFile, "%lg",&trash);
00872 #if CPIXEVERBOSITY > 0
00873 printf("\n Warning: Element '%s' ignored (not present in sample).",tempchem);
00874 #endif
00875 }
00876 }
00877 fclose(CalcFlagsFile);
00878
00879 if(AreasFormat==2 && strcmp(dummy,"CALIB"))
00880 {fprintf(stderr,"\nERROR: Bad DT format in '%s'\n",CalcFlagsFileNm);exit(1);}
00881 if(AreasFormat==1 && strcmp(dummy,"END_DATA"))
00882 {fprintf(stderr,"\nERROR: 'END_DATA' not found in '%s'\n",CalcFlagsFileNm);exit(1);}
00883 if(nread==0){fprintf(stderr,"\nERROR: '%s' contained no valid data\n",CalcFlagsFileNm);exit(1);}
00884
00885 return(0);
00886 }
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934 int readXYld(const char *XYldFileNm, const int *PresentElems, const CPIXERESULTS *CalcFlags, int MaxZinsample, double *CalEner, XrayYield **XYldArray)
00935 {
00936 FILE *XYldFile;
00937 char dummy[LONGSTRINGLENGTH];
00938 int maxZ;
00939 XrayYield *pXYld;
00940 int i,j,tempZ,result,iel;
00941 ChemSymb tempchem;
00942 double natmass,ug2at, trash;
00943 const CalibYld *pFlag;
00944 int atomicunits=0;
00945
00946 XYldFile = fopen(XYldFileNm, "r");
00947 if (XYldFile == NULL)
00948 {fprintf(stderr,"\nERROR: Could not open file '%s' for read.\n",XYldFileNm);exit(1);}
00949
00950 do {
00951 fscanf(XYldFile,"%255s",dummy);
00952 if(feof(XYldFile)) {fprintf(stderr,"\nERROR: 'CALENER' not found in '%s'\n",XYldFileNm);exit(1);}
00953 } while (strcasecmp(dummy, "CALENER"));
00954
00955 fscanf(XYldFile, "%lf", CalEner);
00956
00957 do {
00958 fscanf(XYldFile,"%255s",dummy);
00959 if(feof(XYldFile)) {fprintf(stderr,"\nERROR: 'MAXZ' not found in '%s'\n",XYldFileNm);exit(1);}
00960 } while (strcasecmp(dummy, "MAXZ"));
00961
00962 fscanf(XYldFile, "%d", &maxZ);
00963 if(MaxZinsample>maxZ){fprintf(stderr,"\nERROR: Calib. file '%s' maxZ=%d<%d\n",XYldFileNm,maxZ,MaxZinsample);exit(1);}
00964
00965
00966 *XYldArray=(XrayYield*)calloc(MaxZinsample+1,sizeof(XrayYield));
00967 if (*XYldArray==NULL){fprintf(stderr,"\n Error allocating memory (XYldArray)\n");exit(1);}
00968
00969 do {
00970 fscanf(XYldFile,"%255s",dummy);
00971 if(feof(XYldFile)) {fprintf(stderr,"\nERROR: 'UNITS' not found in '%s'\n",XYldFileNm);exit(1);}
00972 } while (strcasecmp(dummy, "UNITS"));
00973
00974 fscanf(XYldFile, "%255s",dummy);
00975 if(!strcasecmp(dummy, "atom"))atomicunits=1;
00976 else if(!strcasecmp(dummy, "mass"))atomicunits=0;
00977 else {fprintf(stderr,"\nERROR: unknown UNITS ('%s') in '%s'. Valid values are 'atom' or mass'\n",dummy,XYldFileNm);exit(1);}
00978
00979 do {
00980 fscanf(XYldFile,"%255s",dummy);
00981 if(feof(XYldFile)) {fprintf(stderr,"\nERROR: 'DATA' not found in '%s'\n",XYldFileNm);exit(1);}
00982 } while (strcasecmp(dummy, "DATA"));
00983
00984
00985 for(result=0,tempZ=0;!feof(XYldFile) && tempZ!=MaxZinsample;){
00986 fscanf(XYldFile, "%d", &tempZ);
00987 if(tempZ<1 || tempZ>MaxZinsample || (*XYldArray)[tempZ].atnum != 0){
00988 fprintf(stderr,"\nERROR: Bad format in Calib. file '%s' (Z=%d)\n",XYldFileNm,tempZ);
00989 exit(1);
00990 }
00991 fscanf(XYldFile,"%3s",tempchem);
00992 if(tempZ != symbol2Z(tempchem)){
00993 fprintf(stderr,"\nERROR: Bad format in Calib. file '%s' (Z=%d)\n",XYldFileNm,tempZ);
00994 exit(1);
00995 }
00996 if(PresentElems[tempZ]){
00997 result++;
00998 pXYld=&(*XYldArray)[tempZ];
00999 pXYld->atnum=tempZ;
01000 strcpy(pXYld->symb, tempchem);
01001 for(iel=0;CalcFlags[iel].atnum!=tempZ;iel++){}
01002
01003 pFlag=&CalcFlags[iel].simareas;
01004
01005 if(!atomicunits){
01006 Z2mass(tempZ, &natmass,'n');
01007 ug2at=natmass/602.2141;
01008
01009 }
01010 else ug2at=1;
01011
01012
01013 for(i=1;i<=3;i++) fscanf(XYldFile, "%lg", &pXYld->ener.K_[i]);
01014 for(i=1;i<=3;i++) {
01015 fscanf(XYldFile, "%lg", &pXYld->XYld.K_[i]);
01016 pXYld->XYld.K_[i]*=ug2at;
01017
01018 if(!(int)pFlag->K_[i]){ pXYld->XYld.K_[i]=0. ; pXYld->ener.K_[i]=0.;}
01019 }
01020
01021 for(i=1;i<=3;i++){
01022 for(j=1;j<=3;j++){
01023 fscanf(XYldFile, "%lg", &pXYld->ener.L_[i][j]);
01024 }
01025 for(j=1;j<=3;j++){
01026 fscanf(XYldFile, "%lg", &pXYld->XYld.L_[i][j]);
01027 pXYld->XYld.L_[i][j]*=ug2at;
01028 if(!(int)pFlag->L_[i][j]){ pXYld->XYld.L_[i][j]=0. ; pXYld->ener.L_[i][j]=0.;}
01029 }
01030 }
01031
01032
01033 for(i=1;i<=3;i++) fscanf(XYldFile, "%lg", &pXYld->ener.M_[i]);
01034 for(i=1;i<=3;i++) {
01035 fscanf(XYldFile, "%lg", &pXYld->XYld.M_[i]);
01036 pXYld->XYld.M_[i]*=ug2at;
01037 if(!(int)pFlag->M_[i]){ pXYld->XYld.M_[i]=0. ; pXYld->ener.M_[i]=0.;}
01038 }
01039 #if CPIXEVERBOSITY > 0
01040 printf("\n XyldArray[%2d] (%2s) read", pXYld->atnum,tempchem);
01041 #endif
01042 }
01043 else for(i=0;i<30;i++)fscanf(XYldFile, "%lg",&trash);
01044 }
01045 fclose(XYldFile);
01046
01047 return(result);
01048 }
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092 int readFCK(char *FCKCoefFileNm, int MaxZinsample, FluorCKCoef **FCKCoefArray)
01093 {
01094 FILE *FCKCoefFile;
01095 char dummy[LONGSTRINGLENGTH];
01096 int maxZ;
01097 FluorCKCoef *pFCKCoef;
01098 int i,tempZ;
01099 ChemSymb tempchem;
01100
01101 maxZ=0;
01102 FCKCoefFile= fopen(FCKCoefFileNm, "r");
01103 if (FCKCoefFile == NULL)
01104 {fprintf(stderr,"\nERROR: Could not open file '%s' for read.\n",FCKCoefFileNm);exit(1);}
01105
01106 do {
01107 fscanf(FCKCoefFile,"%255s",dummy);
01108 if(feof(FCKCoefFile)) {fprintf(stderr,"\nERROR: 'MAXZ' not found in '%s'\n",FCKCoefFileNm);exit(1);}
01109 } while (strcasecmp(dummy, "MAXZ"));
01110
01111 fscanf(FCKCoefFile, "%d", &maxZ);
01112 if(MaxZinsample>maxZ){fprintf(stderr,"\nERROR: FCK file '%s' maxZ=%d<%d\n",FCKCoefFileNm,maxZ,MaxZinsample);exit(1);}
01113
01114
01115 *FCKCoefArray=(FluorCKCoef*)calloc(MaxZinsample+1,sizeof(FluorCKCoef));
01116 if (*FCKCoefArray==NULL){fprintf(stderr,"\n Error allocating memory (FCKCoefArray)\n");exit(1);}
01117
01118 do {
01119 fscanf(FCKCoefFile,"%255s",dummy);
01120 if(feof(FCKCoefFile)) {fprintf(stderr,"\nERROR: 'DATA' not found in '%s'\n",FCKCoefFileNm);exit(1);}
01121 } while (strcasecmp(dummy, "DATA"));
01122
01123
01124 for(tempZ=0;!feof(FCKCoefFile) && tempZ!=MaxZinsample;){
01125 fscanf(FCKCoefFile, "%d", &tempZ);
01126 if(tempZ<1 || tempZ>MaxZinsample || (*FCKCoefArray)[tempZ].atnum != 0){
01127 fprintf(stderr,"\nERROR: Bad format in FCKCoef file '%s' (Z=%d)\n",FCKCoefFileNm,tempZ);
01128 exit(1);
01129 }
01130 fscanf(FCKCoefFile,"%3s",tempchem);
01131 if(tempZ != symbol2Z(tempchem)){
01132 fprintf(stderr,"\nERROR: Bad format in FCKCoef file '%s' (Z=%d)\n",FCKCoefFileNm,tempZ);
01133 exit(1);
01134 }
01135 pFCKCoef=&(*FCKCoefArray)[tempZ];
01136 pFCKCoef->atnum=tempZ;
01137
01138
01139 for (i = 1; i <= 9; i++) fscanf(FCKCoefFile, "%lg", &pFCKCoef->w[i]);
01140
01141
01142 fscanf(FCKCoefFile, "%lg%lg%lg", &pFCKCoef->ck[0], &pFCKCoef->ck[1], &pFCKCoef->ck[2]);
01143
01144
01145 fscanf(FCKCoefFile, "%lg%lg%lg", &pFCKCoef->k.K_[1], &pFCKCoef->k.K_[2], &pFCKCoef->k.K_[3]);
01146 for (i = 1; i <= 3; i++) fscanf(FCKCoefFile, "%lg%lg%lg", &pFCKCoef->k.L_[i][1], &pFCKCoef->k.L_[i][2], &pFCKCoef->k.L_[i][3]);
01147 fscanf(FCKCoefFile, "%lg%lg%lg", &pFCKCoef->k.M_[1], &pFCKCoef->k.M_[2], &pFCKCoef->k.M_[3]);
01148
01149
01150 }
01151 fclose(FCKCoefFile);
01152 return(0);
01153 }
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197 int readAbsCoef(char *TotAbsCoefFileNm, int MaxZinsample, const int *PresentElems, const FILTER *Filter, AbsCoef **TotAbsCoefArray)
01198 {
01199 FILE *TotAbsCoefFile;
01200 char dummy[LONGSTRINGLENGTH];
01201 int maxZ;
01202 AbsCoef *pTotAbsCoef;
01203 int i,tempZ;
01204 ChemSymb tempchem;
01205 double trash, natmass;
01206 double mg2at;
01207
01208 TotAbsCoefFile= fopen(TotAbsCoefFileNm, "r");
01209 if (TotAbsCoefFile == NULL)
01210 {fprintf(stderr,"\nERROR: Could not open file '%s' for read.\n",TotAbsCoefFileNm);exit(1);}
01211
01212 do {
01213 fscanf(TotAbsCoefFile,"%255s",dummy);
01214 if(feof(TotAbsCoefFile)) {fprintf(stderr,"\nERROR: 'MAXZ' not found in '%s'\n",TotAbsCoefFileNm);exit(1);}
01215 } while (strcasecmp(dummy, "MAXZ"));
01216
01217 fscanf(TotAbsCoefFile, "%d", &maxZ);
01218 if(MaxZinsample>maxZ){fprintf(stderr,"\nERROR: X-Absorption file '%s' maxZ=%d<%d\n",TotAbsCoefFileNm,maxZ,MaxZinsample);exit(1);}
01219
01220
01221 *TotAbsCoefArray=(AbsCoef*)calloc(MaxZinsample+1,sizeof(AbsCoef));
01222 if (*TotAbsCoefArray==NULL){fprintf(stderr,"\n Error allocating memory (TotAbsCoefArray)\n");exit(1);}
01223
01224 do {
01225 fscanf(TotAbsCoefFile,"%255s",dummy);
01226 if(feof(TotAbsCoefFile)) {fprintf(stderr,"\nERROR: 'DATA' not found in '%s'\n",TotAbsCoefFileNm);exit(1);}
01227 } while (strcasecmp(dummy, "DATA"));
01228
01229
01230 for(tempZ=0;!feof(TotAbsCoefFile) && tempZ!=MaxZinsample;){
01231 fscanf(TotAbsCoefFile, "%d", &tempZ);
01232 if(tempZ<1 || tempZ>MaxZinsample || (*TotAbsCoefArray)[tempZ].atnum != 0){
01233 fprintf(stderr,"\nERROR: Bad format in X-Absorption file '%s' (Z=%d)\n",TotAbsCoefFileNm,tempZ);
01234 exit(1);
01235 }
01236 fscanf(TotAbsCoefFile,"%3s",tempchem);
01237 if(tempZ != symbol2Z(tempchem)){
01238 fprintf(stderr,"\nERROR: Bad format in X-Absorption file '%s' (Z=%d)\n",TotAbsCoefFileNm,tempZ);
01239 exit(1);
01240 }
01241 if(PresentElems[tempZ] || ( tempZ<=Filter->MaxZ && Filter->FilterElems[tempZ] ) ){
01242 pTotAbsCoef=&(*TotAbsCoefArray)[tempZ];
01243 pTotAbsCoef->atnum=tempZ;
01244
01245 Z2mass(tempZ, &natmass,'n');
01246 mg2at=natmass/602214.1;
01247
01248
01249 for (i = 0; i < 23; i++){
01250 fscanf(TotAbsCoefFile, "%lg", &pTotAbsCoef->coefstd[i]);
01251
01252 pTotAbsCoef->coefstd[i]*=mg2at;
01253 }
01254 for (i = 1; i <= 9; i++){
01255 fscanf(TotAbsCoefFile, "%lg%lg%lg", &pTotAbsCoef->enr[i], &pTotAbsCoef->coefenr[i-1][0],&pTotAbsCoef->coefenr[i-1][1]);
01256
01257 pTotAbsCoef->coefenr[i-1][0]*=mg2at;
01258 pTotAbsCoef->coefenr[i-1][1]*=mg2at;
01259 }
01260 #if CPIXEVERBOSITY > 0
01261 printf("\n TotAbsCoef[%2d] (%2s) read", pTotAbsCoef->atnum,tempchem);
01262 #endif
01263 }
01264 else for (i = 0; i < 50; i++) fscanf(TotAbsCoefFile, "%lg", &trash);
01265 }
01266 fclose(TotAbsCoefFile);
01267 return(0);
01268 }
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290 int createSPTs(const char *path, const EXP_PARAM *pexp, int MaxZinsample, const int *PresentElems, double step, SPT **SPTArray)
01291 {
01292 int Z,j;
01293 SPT *pSPT;
01294 double E;
01295 double *nucSP;
01296 char afilename[FILENMLENGTH], bfilename[FILENMLENGTH];
01297
01298 snprintf(afilename,FILENMLENGTH,"%sSCOEF.95A",path);
01299 snprintf(bfilename,FILENMLENGTH,"%sSCOEF.95B",path);
01300 readstopcoef(afilename, bfilename);
01301
01302
01303
01304 *SPTArray=(SPT*)calloc(MaxZinsample+1,sizeof(SPT));
01305 if (*SPTArray==NULL){fprintf(stderr,"\n Error allocating memory (SPTArray)\n");exit(1);}
01306
01307 for(Z=1; Z<=MaxZinsample ;Z++){
01308 if(PresentElems[Z]){
01309 pSPT=&(*SPTArray)[Z];
01310
01311 pSPT->Emax=1.1*pexp->BeamEner;
01312 pSPT->Estep=step;
01313 pSPT->logmode=0;
01314 pSPT->nrows=1+(int)ceil(pSPT->Emax/pSPT->Estep);
01315
01316
01317 pSPT->E=(double*)malloc(pSPT->nrows*sizeof(double));
01318 if (pSPT->E==NULL){fprintf(stderr,"\n Error allocating memory (SPTArray[%d].E)\n",Z);exit(1);}
01319 pSPT->S=(double*)malloc(pSPT->nrows*sizeof(double));
01320 if (pSPT->S==NULL){fprintf(stderr,"\n Error allocating memory (SPTArray[%d].S)\n",Z);exit(1);}
01321 pSPT->dSdE=(double*)malloc(pSPT->nrows*sizeof(double));
01322 if (pSPT->dSdE==NULL){fprintf(stderr,"\n Error allocating memory (SPTArray[%d].dSdE)\n",Z);exit(1);}
01323
01324 nucSP=(double*)malloc(pSPT->nrows*sizeof(double));
01325 if (nucSP==NULL){fprintf(stderr,"\n Error allocating memory (nucSP)\n");exit(1);}
01326
01327 for(j=0 ,E=0; j< pSPT->nrows ; j++, E+=step)pSPT->E[j]=E;
01328
01329 stop96d(pexp->ion.Z, Z, pexp->ion.IM, pSPT->E, pSPT->nrows, pSPT->S);
01330 nuclearstopping_ZBL(pexp->ion.Z, Z, pexp->ion.IM, (double)(-1.), pSPT->E, pSPT->nrows, nucSP);
01331
01332 for(pSPT->Smax=0., j=0 ; j< pSPT->nrows ; j++){
01333 pSPT->S[j] += nucSP[j];
01334 pSPT->S[j] *=0.001;
01335 if(pSPT->Smax < pSPT->S[j]) pSPT->Smax = pSPT->S[j];
01336 }
01337 for(j=0 ; j< pSPT->nrows-1 ; j++){
01338 pSPT->dSdE[j]=(pSPT->S[j+1] - pSPT->S[j])/(pSPT->E[j+1] - pSPT->E[j]);
01339 }
01340 pSPT->dSdE[pSPT->nrows-1]=pSPT->dSdE[pSPT->nrows -2];
01341
01342 free(nucSP);
01343 #if CPIXEVERBOSITY > 0
01344 printf("\n Created SP table for Z=%2d (%d rows)",Z,pSPT->nrows);
01345 #endif
01346 }
01347 }
01348
01349 return(0);
01350 }
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361 double getSP(const COMPOUND *pcmp, const SPT *SPTArray, double E)
01362 {
01363 int i,j;
01364 double SP;
01365 const SPT *pspt;
01366
01367
01368 for(SP=0, i=0 ; i< pcmp->nelem ; i++){
01369 pspt= &SPTArray[pcmp->elem[i].Z];
01370 j=(int)floor(E / pspt->Estep);
01371 SP+= (pspt->S[j] + pspt->dSdE[j]*(E - pspt->E[j]) )* pcmp->xn[i];
01372 }
01373 return (SP);
01374 }
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391 int initlyrarray(const EXP_PARAM *pexp, const foil *MatArray, const XrayYield *XYldArray, const AbsCoef *TotAbsCoefArray, const SPT *SPTArray, const int *PresentElems, int NFoil, int *NFoilUsed, LYR **plyrarray)
01392 {
01393 int i;
01394 int Eovermin;
01395 double MajAbsCoef;
01396 LYR *plyr, *plyrold;
01397
01398 *plyrarray=(LYR*)calloc(NFoil+1,sizeof(LYR));
01399 if (*plyrarray==NULL){fprintf(stderr,"\n Error allocating memory (lyrarray)\n");exit(1);}
01400
01401
01402 plyr=&(*plyrarray)[0];
01403
01404
01405
01406
01407 plyr->FoilOutEner=pexp->BeamEner;
01408 plyr->absolutepos=0.;
01409 plyr->ThickIn=0.;
01410
01411 for(Eovermin=1, i=1; i<=NFoil && Eovermin; i++){
01412
01413
01414
01415
01416
01417
01418 plyrold=plyr;
01419 plyr=&(*plyrarray)[i];
01420 plyr->absolutepos=plyrold->absolutepos + plyrold->ThickIn;
01421 plyr->FoilInEner=plyrold->FoilOutEner;
01422 plyr->pFoil=&MatArray[i-1];
01423 initlyr(pexp, XYldArray, TotAbsCoefArray, PresentElems, plyr, &MajAbsCoef);
01424 createsublyrs(pexp, &MatArray[i-1], SPTArray, MajAbsCoef, plyr);
01425 Eovermin=(plyr->FoilOutEner > pexp->FinalEner);
01426 }
01427
01428
01429
01430
01431 *NFoilUsed=i-1;
01432 if(*NFoilUsed<NFoil){
01433 #if CPIXEVERBOSITY >0
01434 printf("\n\nWarning: Layer %d (and deeper) Have been ignored during calculation\n",*NFoilUsed+1);
01435 #endif
01436 }
01437
01438 return(0);
01439 }
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456 int initlyr(const EXP_PARAM *pexp, const XrayYield *XYldArray, const AbsCoef *TotAbsCoefArray, const int *PresentElems, LYR *plyr, double *MACoef)
01457 {
01458 int i,j,jj,ll,Z;
01459
01460 CalibYld *AbsFac;
01461 XrayYield *ResYld;
01462 double geomcorr;
01463
01464
01465 plyr->NumOfTrc=plyr->pFoil->nfoilelm;
01466
01467
01468
01469
01470 plyr->ResYldArray=(XrayYield*)calloc(plyr->NumOfTrc,sizeof(XrayYield));
01471 if (plyr->ResYldArray==NULL){fprintf(stderr,"\n Error allocating memory (plyr->ResYldArray)\n");exit(1);}
01472
01473 plyr->SecResArray=(SecResType*)calloc(plyr->NumOfTrc,sizeof(SecResType));
01474 if (plyr->SecResArray==NULL){fprintf(stderr,"\n Error allocating memory (plyr->SecResArray)\n");exit(1);}
01475
01476
01477 plyr->TrcUse=(int*)calloc(plyr->NumOfTrc,sizeof(int));
01478 if (plyr->TrcUse==NULL){fprintf(stderr,"\n Error allocating memory (plyr->TrcUse)\n");exit(1);}
01479
01480
01481 plyr->NeedSFC=(int*)calloc(plyr->NumOfTrc,sizeof(int));
01482 if (plyr->NeedSFC==NULL){fprintf(stderr,"\n Error allocating memory (plyr->NeedSFC)\n");exit(1);}
01483
01484
01485
01486
01487 plyr->TrcAtnum=(int*)calloc(plyr->NumOfTrc,sizeof(int));
01488 if (plyr->TrcAtnum==NULL){fprintf(stderr,"\n Error allocating memory (plyr->TrcAtnum)\n");exit(1);}
01489
01490
01491 plyr->dimTrans=pexp->simpar.MaxZinsample + 1;
01492 plyr->Trans=(CalibYld*)calloc(plyr->dimTrans,sizeof(CalibYld));
01493 if (plyr->Trans==NULL){fprintf(stderr,"\n Error allocating memory (plyr->Trans)\n");exit(1);}
01494
01495
01496 geomcorr= 1. / pexp->cosDet;
01497 for(Z=1;Z<plyr->dimTrans;Z++){
01498 if(PresentElems[Z]){
01499 Transmission(XYldArray, TotAbsCoefArray, Z, plyr->pFoil, geomcorr, (CalibYld*)NULL, &plyr->Trans[Z]);
01500 }
01501 }
01502
01503
01504
01505 for (*MACoef=0, i = 0; i < plyr->NumOfTrc; i++){
01506
01507 plyr->TrcUse[i]= (plyr->pFoil->comp.elem[i].Z > minK);
01508 if (plyr->TrcUse[i]) {
01509
01510
01511
01512
01513 plyr->ResYldArray[i]=XYldArray[plyr->pFoil->comp.elem[i].Z];
01514
01515 plyr->SecResArray[i].Pk.atnum=plyr->pFoil->comp.elem[i].Z;
01516 for(j=0;j<3;j++){plyr->SecResArray[i].Pk.area[j][0]=1; plyr->SecResArray[i].Pk.area[j][1]=1;}
01517
01518
01519 ResYld=&(plyr->ResYldArray[i]);
01520 plyr->TrcAtnum[i] = ResYld->atnum;
01521 AbsFac= &(plyr->SecResArray[i].SR.AbsFact);
01522
01523 if (ResYld->ener.K_[1] > 0 && ResYld->atnum < maxK) {
01524 for (jj = 1; jj <= 3; jj++) {
01525 AbsFac->K_[jj] = TotAbsor(TotAbsCoefArray, &plyr->pFoil->comp, ResYld->ener.K_[jj]);
01526 if (*MACoef < AbsFac->K_[jj]) *MACoef = AbsFac->K_[jj];
01527 }
01528 }
01529 if (ResYld->ener.M_[1] > 0 && ResYld->atnum > minM) {
01530 for (jj = 1; jj <= 3; jj++) {
01531 AbsFac->M_[jj] = TotAbsor(TotAbsCoefArray, &plyr->pFoil->comp, ResYld->ener.M_[jj]);
01532
01533
01534 }
01535 }
01536 if (ResYld->ener.L_[1][1] > 0 && ResYld->atnum > minL) {
01537 for (jj = 1; jj <= 3; jj++) {
01538 for (ll = 1; ll <= 3; ll++) {
01539 AbsFac->L_[jj][ll] = TotAbsor(TotAbsCoefArray, &plyr->pFoil->comp, ResYld->ener.L_[jj][ll]);
01540 if (*MACoef < AbsFac->L_[jj][ll]) *MACoef = AbsFac->L_[jj][ll];
01541 }
01542 }
01543 }
01544 }
01545 }
01546 return(0);
01547 }
01548
01549
01550 int readFilter(const char *FilterDefFileNm, FILTER *Filter)
01551 {
01552
01553 FILE *FilterDefFile;
01554 char dummy[LONGSTRINGLENGTH];
01555 int i,tempZ,j;
01556 foil *pfoil;
01557 double mg2at,natmass;
01558
01559
01560 Filter->geomcorr=1.;
01561
01562 FilterDefFile = fopen(FilterDefFileNm, "r");
01563 if (FilterDefFile == NULL)
01564 {fprintf(stderr,"\nERROR: Could not open file '%s' for read.\n",FilterDefFileNm);exit(1);}
01565
01566
01567 do {
01568 fscanf(FilterDefFile,"%255s",dummy);
01569 } while (strcasecmp(dummy, "NUMBER_OF_FOILS"));
01570
01571 fscanf(FilterDefFile, "%d", &Filter->nlyr);
01572
01573
01574
01575 Filter->foil=(foil*)malloc((Filter->nlyr)*sizeof(foil));
01576 if (Filter->foil==NULL){fprintf(stderr,"\n Error allocating memory (Filter->foil)\n");exit(1);}
01577
01578 for (Filter->MaxZ=0, i = 0; i < Filter->nlyr ; i++) {
01579 pfoil=&(Filter->foil[i]);
01580 do {
01581 fscanf(FilterDefFile,"%255s",dummy);
01582 } while (strcasecmp(dummy, "FOIL"));
01583
01584 fscanf(FilterDefFile, "%lg %10s", &pfoil->thick, dummy);
01585 if(strcasecmp(dummy,"cm2") && strcasecmp(dummy,"mg")){
01586 fprintf(stderr,"\n Error: Bad syntax in filter definition file: '%s' is not a known thickness unit\n",dummy);exit(1);
01587 }
01588 fscanf(FilterDefFile, "%d", &pfoil->nfoilelm);
01589 tempZ=readCOMPOUND(FilterDefFile, pfoil->nfoilelm, &pfoil->comp);
01590 if(Filter->MaxZ < tempZ) Filter->MaxZ = tempZ;
01591
01592 if(!strcasecmp(dummy,"mg")){
01593
01594 for(natmass=0, j=0 ; j<pfoil->nfoilelm ; j++) natmass += pfoil->comp.xn[j] * pfoil->comp.elem[j].M;
01595 mg2at=natmass/602214.1;
01596
01597 pfoil->thick /= mg2at;
01598 }
01599
01600 }
01601 fclose(FilterDefFile);
01602
01603 createPresentElems(Filter->MaxZ, Filter->nlyr, Filter->foil, &Filter->FilterElems);
01604
01605 return(0);
01606 }
01607
01608
01609 int FilterTrans(const EXP_PARAM *pexp, const XrayYield *XYldArray, const AbsCoef *TotAbsCoefArray, const int *PresentElems, FILTER *Filter)
01610 {
01611 int Z,i;
01612 CalibYld auxTrans, *pTrans, *pauxTrans;
01613 CalibYld unitTrans={ { 0.0, 1.0, 1.0, 1.0 },
01614 { { 0.0, 0.0, 0.0, 0.0 },
01615 { 0.0, 1.0, 1.0, 1.0 },
01616 { 0.0, 1.0, 1.0, 1.0 },
01617 { 0.0, 1.0, 1.0, 1.0 }},
01618 { 0.0, 1.0, 1.0, 1.0 }};
01619
01620 Filter->dimTrans=pexp->simpar.MaxZinsample + 1;
01621 Filter->Trans=(CalibYld*)calloc(Filter->dimTrans,sizeof(CalibYld));
01622 if (Filter->Trans==NULL){fprintf(stderr,"\n Error allocating memory (Filter->Trans)\n");exit(1);}
01623
01624 for(Z=1;Z<Filter->dimTrans;Z++){
01625 for(Z=1;Z<Filter->dimTrans;Z++)
01626 if(PresentElems[Z]){
01627 pauxTrans=NULL;
01628 pTrans=&Filter->Trans[Z];
01629 *pTrans=unitTrans;
01630
01631 for (i=0 ; i < Filter->nlyr ; i++){
01632 Transmission(XYldArray, TotAbsCoefArray, Z, &Filter->foil[i], Filter->geomcorr, pauxTrans, pTrans);
01633 auxTrans= *pTrans;
01634 pauxTrans=&auxTrans;
01635 }
01636 }
01637 }
01638
01639 return(0);
01640 }
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655 int Transmission(const XrayYield *XYldArray, const AbsCoef *TotAbsCoefArray, int Z, const foil *pFoil, double geomcorr, const CalibYld *pTransOld, CalibYld *pTrans)
01656 {
01657 int jj,ll;
01658 double thickout;
01659 const CalibYld *pXYldener;
01660
01661 thickout=pFoil->thick * geomcorr;
01662 pXYldener=&XYldArray[Z].ener;
01663
01664
01665 if (pXYldener->K_[1] > 0 && Z < maxK) {
01666 for (jj = 1; jj <= 3; jj++) {
01667 pTrans->K_[jj] = exp(-thickout * TotAbsor(TotAbsCoefArray, &pFoil->comp, pXYldener->K_[jj]) );
01668 if(pTransOld!=NULL)
01669 pTrans->K_[jj] *= pTransOld->K_[jj];
01670 }
01671 }
01672
01673 if (pXYldener->M_[1] > 0 && Z > minM) {
01674 for (jj = 1; jj <= 3; jj++) {
01675 pTrans->M_[jj] = exp(-thickout * TotAbsor(TotAbsCoefArray, &pFoil->comp, pXYldener->M_[jj]) );
01676 if(pTransOld!=NULL) pTrans->M_[jj] *= pTransOld->M_[jj];
01677 }
01678 }
01679
01680 if (pXYldener->L_[1][1] > 0 && Z > minL) {
01681 for (jj = 1; jj <= 3; jj++) {
01682 for (ll = 1; ll <= 3; ll++) {
01683 pTrans->L_[jj][ll] = exp(-thickout * TotAbsor(TotAbsCoefArray, &pFoil->comp, pXYldener->L_[jj][ll]) );
01684 if(pTransOld!=NULL) pTrans->L_[jj][ll] *= pTransOld->L_[jj][ll];
01685 }
01686 }
01687 }
01688 return(0);
01689 }
01690
01691
01692
01693
01694
01695
01696
01697
01698 double TotAbsor(const AbsCoef *TotAbsCoefArray, const COMPOUND *cmp, double Xray)
01699 {
01700 int i,iener;
01701 double absaux;
01702 int dimstdener;
01703 const AbsCoef *Absco;
01704 double stdener[23] = { 1.00, 1.25, 1.50, 1.75, 2.00,
01705 2.50, 3.00, 3.50, 4.00, 4.50, 5.00,
01706 5.50, 6.00, 6.50, 7.00, 8.00, 10.0,
01707 12.5, 15.0, 17.5, 20.0, 25.0, 30.0};
01708
01709 dimstdener=23-1;
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721 if (Xray < stdener[0] || Xray >= stdener[dimstdener]) return (0.);
01722
01723 for(iener=1;Xray > stdener[iener];iener++);
01724
01725
01726 for (absaux=0, i = 0; i < cmp->nelem; i++) {
01727 Absco=&(TotAbsCoefArray[cmp->elem[i].Z]);
01728 absaux += cmp->xn[i] * TotAbsor_elemental(iener, Absco, cmp->elem[i].Z, Xray);
01729 }
01730
01731 return(absaux);
01732 }
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742 double TotAbsor_elemental(int iener, const AbsCoef *Absco, int Z, double Xray)
01743 {
01744 int j,limj;
01745 double absaux = 0.0;
01746 double enermaj, enermin, a, b, majcoef, mincoef;
01747 double stdener[23] = { 1.00, 1.25, 1.50, 1.75, 2.00,
01748 2.50, 3.00, 3.50, 4.00, 4.50, 5.00,
01749 5.50, 6.00, 6.50, 7.00, 8.00, 10.0,
01750 12.5, 15.0, 17.5, 20.0, 25.0, 30.0};
01751
01752
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763
01764 enermaj = stdener[iener];
01765 enermin = stdener[iener-1];
01766 majcoef = Absco->coefstd[iener];
01767 mincoef = Absco->coefstd[iener-1];
01768
01769 if(Z<11) limj=0;
01770 else{
01771 if(Z<28) limj=1;
01772 else{
01773 if(Z<52) limj=4;
01774 else limj=9;
01775 }
01776 }
01777
01778 for (j = 1; j <= limj; j++) {
01779 if (Absco->enr[j] > 0 && Absco->enr[j] > enermin && Absco->enr[j] < Xray) {
01780 enermin = Absco->enr[j];
01781 mincoef = Absco->coefenr[j-1][1];
01782 }
01783 if (Absco->enr[j] > 0 && Absco->enr[j] < enermaj && Absco->enr[j] > Xray) {
01784 enermaj = Absco->enr[j];
01785 majcoef = Absco->coefenr[j-1][0];
01786 }
01787 }
01788
01789 a = log(majcoef / mincoef) / log(enermaj / enermin);
01790 b = log(majcoef) - a * log(enermaj);
01791 absaux = exp(a * log(Xray) + b);
01792
01793 return(absaux);
01794 }
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807 int createsublyrs(const EXP_PARAM *pexp, const foil *pMat, const SPT *SPTArray, double MajAbsCoef, LYR *plyr)
01808 {
01809 ESxType ESx1,ESx2,ESx3;
01810 int i,Fpos;
01811 double Range,range1,range2, Smax;
01812
01813
01814 for(Smax=0., i=0 ; i < pMat->nfoilelm ; i++) Smax += SPTArray[pMat->comp.elem[i].Z].Smax * pMat->comp.xn[i];
01815
01816
01817 plyr->ThickIn=pMat->thick/pexp->cosInc;
01818
01819 Fpos=1;
01820 plyr->ESxArray=(ESxType*)malloc((Fpos)*sizeof(ESxType));
01821 if (plyr->ESxArray==NULL){fprintf(stderr,"\n Error allocating memory (plyr->ESxArray)\n");exit(1);}
01822
01823 ESx1.ep = plyr->FoilInEner;
01824 ESx1.stpp = getSP(&pMat->comp, SPTArray, ESx1.ep);
01825 ESx1.x = 0.0;
01826 plyr->ESxArray[Fpos-1]=ESx1;
01827
01828
01829 ESx2.ep = plyr->FoilInEner * 0.90;
01830 ESx2.stpp = getSP(&pMat->comp, SPTArray, ESx2.ep);
01831 ESx2.x = 0.0;
01832
01833 ESx3.ep=pexp->FinalEner;
01834 ESx3.stpp = getSP(&pMat->comp, SPTArray, ESx3.ep);
01835 ESx3.x = 0.0;
01836
01837
01838
01839
01840
01841
01842
01843
01844
01845
01846
01847 SSThick(pexp, pMat, SPTArray, MajAbsCoef, plyr->ThickIn, ESx1, &ESx2, &Fpos, &range1, &plyr->ESxArray);
01848
01849 ESx2= plyr->ESxArray[Fpos - 1];
01850
01851 if (ESx2.x == plyr->ThickIn) {
01852 plyr->FoilOutEner = ESx2.ep;
01853 Range = ESx2.x;
01854 plyr->FESxlen= Fpos;
01855 }
01856 else {
01857 SSThick(pexp, pMat, SPTArray, MajAbsCoef, plyr->ThickIn, ESx2, &ESx3, &Fpos, &range2, &plyr->ESxArray);
01858 ESx3=plyr->ESxArray[Fpos-1];
01859
01860 plyr->FoilOutEner = ESx3.ep;
01861 Range = range1 + range2;
01862 if (Range < plyr->ThickIn) plyr->ThickIn = Range;
01863 plyr->FESxlen = Fpos;
01864 }
01865
01866 return(0);
01867 }
01868
01869
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884 int SSThick(const EXP_PARAM *pexp, const foil *pMat, const SPT *SPTArray, double MajAbsCoef,
01885 double LayerThickness, ESxType ESxin, ESxType *ESxfin, int *pFpos, double *thick, ESxType **ESxA)
01886 {
01887 double tck1, tck2, auxdecis, auxstpchange,auxaux;
01888 ESxType ESxm1, ESxaux;
01889
01890 auxaux=exp(-MajAbsCoef * ESxin.x * pexp->cosFac);
01891 if (auxaux > 1e-7){
01892
01893
01894
01895
01896
01897 auxdecis = exp(MajAbsCoef * (ESxin.x - ESxfin->x) * pexp->cosFac) /auxaux;
01898
01899 }
01900 else auxdecis = 1.0;
01901
01902
01903
01904 auxstpchange= (ESxin.ep / pexp->BeamEner)* fabs(ESxin.stpp - ESxfin->stpp) / ((ESxin.stpp + ESxfin->stpp)/2.);
01905
01906
01907
01908
01909 if ( auxstpchange < 0.005 && auxdecis > 0.997 ){
01910
01911 ESxaux.ep = (ESxin.ep + ESxfin->ep) / 2.;
01912 ESxaux.stpp = getSP(&pMat->comp, SPTArray, ESxaux.ep);
01913 *thick = (ESxin.ep - ESxfin->ep) / ((ESxin.stpp + 4. *ESxaux.stpp + ESxfin->stpp) / 6.);
01914 ESxfin->x = ESxin.x + *thick;
01915
01916 if (ESxfin->x > LayerThickness) {
01917 *thick = LayerThickness - ESxin.x;
01918 ESxfin->x = LayerThickness;
01919 ESxfin->ep = ESxin.ep - 0.5*(ESxin.stpp + ESxfin->stpp) * (*thick) ;
01920 ESxaux.ep = (ESxin.ep + ESxfin->ep) / 2.;
01921 ESxaux.stpp = getSP(&pMat->comp, SPTArray, ESxaux.ep);
01922 }
01923
01924 ESxaux.x = ESxin.x + *thick / 2.;
01925
01926
01927 *ESxA=(ESxType*)realloc(*ESxA,((*pFpos)+2)*sizeof(ESxType));
01928 if (*ESxA==NULL){fprintf(stderr,"\n Error allocating memory (ESxA)\n");exit(1);}
01929
01930 (*ESxA)[*pFpos]=ESxaux;
01931 (*pFpos)++;
01932
01933 (*ESxA)[*pFpos]= *ESxfin;
01934 (*pFpos)++;
01935
01936
01937
01938
01939
01940 }
01941 else{
01942
01943
01944
01945 ESxm1.ep = (ESxin.ep + ESxfin->ep) / 2;
01946 ESxm1.stpp = getSP(&pMat->comp, SPTArray, ESxm1.ep);
01947 ESxm1.x = ESxin.x + (ESxin.ep - ESxm1.ep) / ESxin.stpp;
01948
01949
01950 SSThick(pexp, pMat, SPTArray, MajAbsCoef, LayerThickness, ESxin, &ESxm1, pFpos, &tck1, ESxA);
01951
01952 if (ESxm1.x < LayerThickness) {
01953 SSThick(pexp, pMat, SPTArray, MajAbsCoef, LayerThickness, ESxm1, ESxfin, pFpos, &tck2, ESxA);
01954 *thick = tck1 + tck2;
01955 }
01956 else *thick = tck1;
01957 }
01958 return(0);
01959 }
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974 int integrate_Simpson(const EXP_PARAM *pexp, const AbsCoef *TotAbsCoefArray,
01975 const FluorCKCoef *FCKCoefArray, const XrayYield *XYldArray,
01976 int NFoilUsed, const FILTER *Filter, LYR *plyrarray, CalibYld *XYldSums){
01977 int ilyr, itrans, ii, jj, ll,mm;
01978 LYR *plyr;
01979 CalibYld *AbsFac;
01980 CalibYld *pSSYld, *pSSTrs;
01981 const AbsCoef *AbsC;
01982 const FluorCKCoef *pFCKTrc;
01983 XrayYield *pResYld;
01984 const CalibYld *pXYld;
01985 SecResType *pSecRes;
01986 CalibYld *pXYldSum;
01987 double tckout,tempE,tempM,attfraction;
01988 int tempZ, FirstReg;
01989 const SIM_PARAM *psim;
01990 CalibYld tempTr0;
01991 psim=&pexp->simpar;
01992
01993 for(ilyr=1; ilyr<=NFoilUsed; ilyr++){
01994 plyr=&plyrarray[ilyr];
01995
01996
01997 plyr->SSTrsArray=(CalibYld*)calloc((plyr->NumOfTrc * plyr->FESxlen),sizeof(CalibYld));
01998 if (plyr->SSTrsArray==NULL){fprintf(stderr,"\n Error allocating memory (lyr[layer].SSTrsArray)\n");exit(1);}
01999
02000 plyr->SSYldArray=(CalibYld*)calloc((plyr->NumOfTrc * plyr->FESxlen),sizeof(CalibYld));
02001 if (plyr->SSYldArray==NULL){fprintf(stderr,"\n Error allocating memory (lyr[layer].SSYldArray)\n");exit(1);}
02002
02003
02004
02005
02006 for (jj = 0; jj < plyr->NumOfTrc ; jj++) {
02007 if (plyr->TrcUse[jj]) {
02008
02009 AbsFac= &(plyr->SecResArray[jj].SR.AbsFact);
02010 tempZ=plyr->TrcAtnum[jj];
02011
02012 for (ii = 0; ii < plyr->FESxlen; ii++) {
02013 tckout=plyr->ESxArray[ii].x * pexp->cosFac;
02014 pSSTrs=&(plyr->SSTrsArray[ii + plyr->FESxlen * jj]);
02015
02016 if (tempZ < maxK) {
02017 for (ll = 1; ll <= 3; ll++) {
02018 if (AbsFac->K_[ll] > 0)
02019 pSSTrs->K_[ll] = exp(-AbsFac->K_[ll] * tckout);
02020 }
02021 }
02022 if (tempZ > minM) {
02023 for (ll = 1; ll <= 3; ll++) {
02024 if (AbsFac->M_[ll] > 0)
02025 pSSTrs->M_[ll] = exp(-AbsFac->M_[ll] * tckout);
02026 }
02027 }
02028 if (tempZ > minL) {
02029 for (ll = 1; ll <= 3; ll++) {
02030 for (mm = 1; mm <= 3; mm++) {
02031 if (AbsFac->L_[ll][mm] > 0)
02032 pSSTrs->L_[ll][mm] = exp(-AbsFac->L_[ll][mm] * tckout);
02033 }
02034 }
02035 }
02036 }
02037 }
02038 }
02039
02040
02041
02042 for (jj = 0; jj < plyr->NumOfTrc; jj++) {
02043 if (plyr->TrcUse[jj]) {
02044
02045 tempZ=plyr->TrcAtnum[jj];
02046 Z2mass(tempZ, &tempM, 'n');
02047 pFCKTrc=&FCKCoefArray[tempZ];
02048 AbsC=&TotAbsCoefArray[tempZ];
02049
02050 for (ii = 0; ii < plyr->FESxlen; ii++) {
02051 tempE=plyr->ESxArray[ii].ep;
02052 pSSYld=&( plyr->SSYldArray[ (ii + plyr->FESxlen * jj) ] );
02053
02054 Xprod(AbsC, pFCKTrc, pexp->ion.Z, tempZ, tempM, tempE, pSSYld);
02055
02056 }
02057 }
02058 }
02059
02060 }
02061
02062
02063
02064
02065 for(ilyr=1; ilyr<=NFoilUsed; ilyr++){
02066 plyr=&plyrarray[ilyr];
02067
02068 for (ii = 0; ii < plyr->NumOfTrc ; ii++) {
02069
02070 if (plyr->TrcUse[ii]) {
02071 tempZ=plyr->TrcAtnum[ii];
02072 Z2mass(tempZ, &tempM, 'n');
02073 pFCKTrc=&FCKCoefArray[tempZ];
02074 AbsC=&TotAbsCoefArray[tempZ];
02075 pResYld=&plyr->ResYldArray[ii];
02076 pSecRes=&plyr->SecResArray[ii];
02077 AbsFac= &(plyr->SecResArray[ii].SR.AbsFact);
02078 pXYld=&XYldArray[tempZ].XYld;
02079 pXYldSum=&XYldSums[tempZ];
02080 attfraction=plyr->pFoil->comp.xn[ii];
02081
02082
02083
02084
02085 FirstReg = (ii) * plyr->FESxlen;
02086 pSSTrs=&plyr->SSTrsArray[FirstReg];
02087 pSSYld=&plyr->SSYldArray[FirstReg];
02088
02089
02090
02091
02092 tempTr0=plyr->SSTrsArray[FirstReg];
02093
02094 if (tempZ < maxK) {
02095 for (ll = 1; ll <= 3; ll++) {
02096 tempTr0.K_[ll] *= Filter->Trans[tempZ].K_[ll];
02097 for(itrans=ilyr-1 ; itrans>0 ; itrans--){
02098 tempTr0.K_[ll] *= plyrarray[itrans].Trans[tempZ].K_[ll];
02099 }
02100 }
02101 }
02102
02103 if (tempZ > minM) {
02104 for (ll = 1; ll <= 3; ll++) {
02105 tempTr0.M_[ll] *= Filter->Trans[tempZ].M_[ll];
02106 for(itrans=ilyr-1 ; itrans>0 ; itrans--){
02107 tempTr0.M_[ll] *= plyrarray[itrans].Trans[tempZ].M_[ll];
02108 }
02109 }
02110 }
02111
02112 if (tempZ > minL) {
02113 for (ll = 1; ll <= 3; ll++) {
02114 for (mm = 1; mm <= 3; mm++) {
02115 tempTr0.L_[ll][mm] *= Filter->Trans[tempZ].L_[ll][mm];
02116 for(itrans=ilyr-1 ; itrans>0 ; itrans--){
02117 tempTr0.L_[ll][mm] *= plyrarray[itrans].Trans[tempZ].L_[ll][mm];
02118 }
02119 }
02120 }
02121 }
02122
02123 PenInteg(tempZ, AbsFac, plyr->ESxArray, pSSYld,
02124 pSSTrs, &tempTr0, plyr->FESxlen,
02125 plyr->NeedSFC[ii], psim->AllowXEqCalc, plyr->absolutepos, pexp->cosInc,
02126 &pResYld->XYld, &pSecRes->SR.SFCr, &pSecRes->SR.Xeq);
02127
02128 deNormalize(pexp, AbsC ,pFCKTrc, tempZ, tempM, attfraction, pXYld, pResYld, pXYldSum);
02129
02130 }
02131 }
02132 }
02133
02134
02135 return(0);
02136 }
02137
02138
02139
02140
02141
02142
02143
02144
02145
02146
02147
02148
02149
02150
02151 int Xprod(const AbsCoef *AbsC, const FluorCKCoef *pFCK, atomicnumber Z1, atomicnumber Z2, double M2 , double ener, CalibYld *XYld)
02152 {
02153 int i, j;
02154 SecXL XLaux;
02155 double auxsec;
02156 CalibYld CYldNul = { { 0.0, 0.0, 0.0, 0.0 },
02157 { { 0.0, 0.0, 0.0, 0.0 },
02158 { 0.0, 0.0, 0.0, 0.0 },
02159 { 0.0, 0.0, 0.0, 0.0 },
02160 { 0.0, 0.0, 0.0, 0.0 }},
02161 { 0.0, 0.0, 0.0, 0.0 }};
02162 double barn_to_cm21e15;
02163
02164 barn_to_cm21e15=1e-9;
02165
02166
02167 if(Z1!=1){fprintf(stderr,"\n Error: Xprod() currently supports only H ions\n");exit(1);}
02168
02169 *XYld = CYldNul;
02170 switch (Z2) {
02171
02172 case 10:
02173 case 11:
02174 case 12:
02175 case 13:
02176 case 14:
02177 auxsec = PaulX(ener, Z2);
02178 XYld->K_[1] = auxsec * pFCK->k.K_[1] * barn_to_cm21e15;
02179 break;
02180
02181 case 54:
02182 case 55:
02183 case 56:
02184 case 57:
02185 case 58:
02186 case 59:
02187 ReisX(AbsC,pFCK, ener, Z2, M2, XLaux);
02188 for (i = 1; i <= 3; i++) {
02189 for (j = 1; j <= 3; j++)
02190 XYld->L_[i][j] = XLaux[4 - i] * pFCK->k.L_[i][j] * barn_to_cm21e15;
02191 }
02192 break;
02193
02194 default:
02195 if (Z2 >= 15 && Z2 <minL) {
02196 auxsec = PaulX(ener, Z2);
02197 XYld->K_[1] = auxsec * pFCK->k.K_[1] * barn_to_cm21e15;
02198 XYld->K_[2] = auxsec * pFCK->k.K_[2] * barn_to_cm21e15;
02199 }
02200 else if (Z2 >= minL && Z2 < maxK) {
02201 auxsec = PaulX(ener, Z2);
02202 ReisX(AbsC,pFCK, ener, Z2, M2, XLaux);
02203 for (i = 1; i <= 3; i++) {
02204 XYld->K_[i] = auxsec * pFCK->k.K_[i] * barn_to_cm21e15;
02205 for (j = 1; j <= 3; j++)
02206 XYld->L_[i][j] = XLaux[4 - i] * pFCK->k.L_[i][j] * barn_to_cm21e15;
02207 }
02208 }
02209 else if (Z2 >= minM && Z2 <= 99) {
02210 ReisX(AbsC,pFCK, ener, Z2, M2, XLaux);
02211 for (i = 1; i <= 3; i++) {
02212 for (j = 1; j <= 3; j++)
02213 XYld->L_[i][j] = XLaux[4 - i] * pFCK->k.L_[i][j] * barn_to_cm21e15;
02214 }
02215 }
02216 break;
02217 }
02218 return(0);
02219 }
02220
02221
02222
02223
02224
02225
02226
02227
02228
02229
02230
02231 double PaulX(double ener, atomicnumber z)
02232 {
02233 static double sc1 = -2.1717, sc2 = 10.8883, sc3 = 9.45875, sc4 = 0.975316,
02234 sc5 = 0.0165458, sc6 = 1.00859, sc7 = 0.0474606;
02235
02236 static double ylim[4] = { 0., -0.86, -0.582, -0.037 };
02237
02238 static double C[8][7] = {
02239 { 0., 0. , 0. , 0. , 0. , 0. , 0. },
02240 { 0., 4.97159 , -0.0334597 , 4.56721e-3, -4.17618e-6, -0.0152467 , 9.11304e-4 },
02241 { 0., -3.89274 , -0.883283 , -0.0177272 , 1.03168e-4, 0.824937 , 0.0110194 },
02242 { 0., 597612.0 , 597919.0 , 25220.1 , -37.2554 , -362099.0 , -13942.3 },
02243 { 0., 0.107444 , -4.47727e-3, 1.30581e-4, -1.9793e-6 , 1.00964e-8, 0.0 },
02244 { 0., 0.113657 , -8.4197e-3 , 2.40606e-4, -2.95528e-6, 1.26726e-8, 0.0 },
02245 { 0., 0.0105593, 7.4928e-4 , -1.30255e-5, 9.19824e-8, 0.0 , 0.0 },
02246 { 0., -0.0306492, 1.00377e-3, -1.68953e-5, 8.74937e-8, 0.0 , 0.0 }};
02247
02248 long i;
02249 double sc = 0.0;
02250 double MeV,f, pauly, paule, xx, auxpp1, auxpp2, auxpp3;
02251 double auxl[7];
02252 double b[8];
02253
02254
02255 MeV = ener*0.001;
02256 paule = log10(MeV / (z * z));
02257 xx = paule / 1.15 + 2.22;
02258 pauly = PaulX_y(MeV, z);
02259 if (pauly < ylim[1])
02260 sc = 0.0;
02261 if (pauly >= ylim[1] && pauly <= ylim[2])
02262 sc = sc1 - sc2 * pauly - sc3 * pauly * pauly;
02263 if (pauly > ylim[2] && pauly <= ylim[3])
02264 sc = sc4 - sc5 * cos(13.6 * (pauly + 0.393));
02265 if (pauly > ylim[3])
02266 sc = sc6 + sc7 * cos(6.23 * (pauly - 0.33));
02267 for (i = 1; i <= 7; i++) {
02268 b[i] = C[i][1] + C[i][2] * z + C[i][3] * z * z + C[i][4] * z * z * z;
02269 switch (i) {
02270
02271 case 1:
02272 case 2:
02273 case 3:
02274 b[i] /= 1 + C[i][5] * z + C[i][6] * z * z;
02275 break;
02276
02277 case 4:
02278 case 5:
02279 b[i] += C[i][5] * z * z * z * z;
02280 break;
02281 }
02282 }
02283 for (i = 3; i <= 6; i++)
02284 auxl[i] = PaulX_lp(xx, i);
02285 auxpp1 = paule - b[3];
02286 auxpp1 *= auxpp1;
02287 auxpp2 = b[4] * PaulX_lp(xx, 3);
02288 auxpp3 = b[5] * PaulX_lp(xx, 4) + b[6] * PaulX_lp(xx, 5) + b[7] * PaulX_lp(xx, 6);
02289 f = b[1] + b[2] * auxpp1 + auxpp2 + auxpp3;
02290 return (sc * exp(f * log(10.0) - 2.2 * log(z)));
02291 }
02292
02293
02294
02295
02296
02297
02298
02299
02300
02301
02302
02303
02304
02305 double PaulX_y(double MeV, atomicnumber z)
02306 {
02307 static double teta1 = 0.313076, teta2 = 0.149231, teta3 = 5.54982e-5,
02308 teta4 = 3.7093e-6, teta5 = 0.166608;
02309 double auxz = z;
02310 double eta, theta, TEMP;
02311
02312 TEMP = auxz - 0.3;
02313 eta = 40.0283 * MeV / (TEMP * TEMP);
02314 theta = teta1 + teta2 * auxz - teta3 * auxz * auxz + teta4 * auxz * auxz * auxz;
02315 theta /= 1 + teta5 * auxz;
02316 return (log10(2 * sqrt(eta) / theta));
02317 }
02318
02319
02320
02321
02322
02323
02324
02325
02326
02327 double PaulX_lp(double x, long p)
02328 {
02329 double prr = 0.0;
02330 double TEMP, TEMP1;
02331
02332 switch (p) {
02333
02334 case 3:
02335 prr = 0.5 * (5 * x * x * x - 3 * x);
02336 break;
02337
02338 case 4:
02339 TEMP = x * x;
02340 prr = 0.125 * (35 * (TEMP * TEMP) - 30 * x * x + 3);
02341 break;
02342
02343 case 5:
02344 TEMP = x * x;
02345 prr = 0.125 * (63 * x * (TEMP * TEMP) - 70 * x * x * x + 15 * x);
02346 break;
02347
02348 case 6:
02349 TEMP = x * x;
02350 TEMP1 = x * x;
02351 prr = 0.0625 * (231 * x * x * (TEMP * TEMP) - 315 * (TEMP1 * TEMP1) +
02352 105 * x * x - 5);
02353 break;
02354 }
02355 return (prr);
02356 }
02357
02358
02359
02360
02361
02362
02363
02364
02365
02366
02367
02368
02369
02370
02371 int ReisX(const AbsCoef *AbsC, const FluorCKCoef *pFCK, double ener, atomicnumber z, double M2, double *sigmaXL)
02372 {
02373
02374 SecXL ion, ionuni;
02375 int i;
02376 double xi[4];
02377 int seted = 0;
02378 double TEMP;
02379 double enr;
02380 FwTipo tipo;
02381
02382 int Ncam, Zpr, nium;
02383 double MeV, Hr, cau, a02, Z2b, z2, z4, miu, EnrSm1, Mpr, MprMeV, MprUAt, a2s, v1,Iabs, q0sb,
02384 theta, ksi, zeta, ys, ys2, d, mRs, ksir, xcb, zcbs, cbe, etam, ratnorm;
02385
02386 MeV = ener * 1e-3;
02387 Zpr = 1;
02388 Mpr = 1.007;
02389 Ncam = 2;
02390
02391 Hr = 27.2116;
02392 cau = 137.03604;
02393 a02 = 2.800283608e-21;
02394
02395 tipo = L;
02396 Z2b = (double)(z) - 4.15;
02397 z2 = Z2b * Z2b;
02398 z4 = z2 * z2;
02399
02400 MprMeV = Mpr * MEVAMU;
02401 MprUAt = Mpr / UATMASS ;
02402 EnrSm1 = MeV / MprMeV;
02403 miu = Mpr / (1 + Mpr / M2) / UATMASS;
02404 a2s = (double)(Ncam * Ncam) / Z2b;
02405 TEMP = 1 + EnrSm1;
02406 TEMP = 1 / (TEMP * TEMP);
02407 v1 = cau * sqrt(1 - TEMP);
02408 d = (double)Zpr * z / (miu * (v1 * v1));
02409 for (i = 1; i <= 3; i++) {
02410 enr=AbsC->enr[i+1];
02411 if (enr > 0) {
02412 seted = 1;
02413 Iabs = enr * 1e3;
02414 q0sb = Iabs / (Hr * v1);
02415 theta = (double)(Ncam * Ncam * 2) * Iabs / (z2 * Hr);
02416 ksi = 2 * v1 / (theta * (Z2b / (double)Ncam));
02417 TEMP = ReisX_gs(tipo, i, ksi);
02418 TEMP -= ReisX_hs(tipo, i, ksi, theta);
02419 zeta = 1. + (double)(Zpr * 2) * TEMP / (Z2b * theta);
02420
02421 TEMP=z2/(cau*cau*ksi/zeta);
02422 if (i == 1) ys = TEMP * 0.40 / (double)Ncam ;
02423 else ys = TEMP * 0.15 ;
02424 ys2 = ys * ys;
02425 mRs = sqrt(1. + 1.1 * ys2) + ys;
02426 ksir = sqrt(mRs) * ksi;
02427 xi[i] = 1. / ksir;
02428
02429 xcb = 2. * M_PI * d * q0sb * zeta;
02430 zcbs = sqrt(1. - 4. * zeta / (theta * miu * ksi * ksi * mRs));
02431 switch (i) {
02432 case 1:
02433 nium = 9;
02434 break;
02435 case 2:
02436 case 3:
02437 nium = 11;
02438 break;
02439 case 4:
02440 case 5:
02441 nium = 13;
02442 break;
02443 }
02444 TEMP = xcb / (zcbs * (1 + zcbs));
02445 cbe = (double)nium * ReisX_En(TEMP, nium + 1);
02446 TEMP = theta * ksir / ((double)(Ncam * 2));
02447 etam = TEMP * TEMP;
02448 TEMP = (double)Zpr / Z2b;
02449 ratnorm = 8. * M_PI * (a02 / (etam * theta)) * (TEMP * TEMP) * cbe / BARNTOM2;
02450 ionuni[i] = ReisX_polisec(i, ksir, theta);
02451 ion[i] = ionuni[i] * ratnorm;
02452 }
02453 }
02454 sigmaXL[1] = ReisX_g(1, z, xi[1]) * pFCK->w[2] * ion[1];
02455 sigmaXL[2] = ReisX_g(2, z, xi[2]) * pFCK->w[3] * (pFCK->ck[0] * ion[1] + ion[2]);
02456 sigmaXL[3] = ReisX_g(3, z, xi[3]) * pFCK->w[4] *
02457 ((pFCK->ck[1] + pFCK->ck[0] * pFCK->ck[2]) * ion[1] + pFCK->ck[2] * ion[2] + ion[3]);
02458
02459 return(0);
02460 }
02461
02462
02463
02464
02465
02466
02467
02468
02469
02470
02471
02472
02473
02474 double ReisX_gs(FwTipo T, int SS, double ksis)
02475 {
02476
02477 static double gK[9] = {
02478 1.0, 1.0, 9.0, 31.0, 98.0, 12.0, 25.0, 4.2, 0.515
02479 };
02480
02481 static double gL1[9] = {
02482 1.0, 1.0, 9.0, 31.0, 49.0, 162.0, 63.0, 18.0, 1.97
02483 };
02484
02485 static double gL23[10] = {
02486 1.0, 1.0, 10.0, 45.0, 102.0, 331.0, 6.7, 58.0, 7.8, 0.888
02487 };
02488
02489 double ksis2, ksis3, ksis4, ksis5, ksis6, ksis7, ksis8;
02490 double gsaux = 0.0;
02491 double gsaux2;
02492
02493 ksis2 = ksis * ksis;
02494 ksis3 = ksis * ksis2;
02495 ksis4 = ksis2 * ksis2;
02496 ksis5 = ksis2 * ksis3;
02497 ksis6 = ksis3 * ksis3;
02498 ksis7 = ksis3 * ksis4;
02499 ksis8 = ksis4 * ksis4;
02500 switch (T) {
02501
02502 case K:
02503 gsaux = gK[1] + gK[2] * ksis + gK[3] * ksis2 + gK[4] * ksis3;
02504 gsaux += gK[5] * ksis4 + gK[6] * ksis5 + gK[7] * ksis6 + gK[8] * ksis7;
02505 gsaux2 = 1 + ksis;
02506 gsaux2 *= gsaux2 * gsaux2;
02507 gsaux2 *= gsaux2 * gsaux2;
02508 gsaux /= gsaux2;
02509 break;
02510
02511 case L:
02512 if (SS == 1) {
02513 gsaux = gL1[1] + gL1[2] * ksis + gL1[3] * ksis2 + gL1[4] * ksis3;
02514 gsaux += gL1[5] * ksis4 + gL1[6] * ksis5 + gL1[7] * ksis6 + gL1[8] * ksis7;
02515 gsaux2 = 1 + ksis;
02516 gsaux2 *= gsaux2 * gsaux2;
02517 gsaux2 *= gsaux2 * gsaux2;
02518 gsaux /= gsaux2;
02519 } else {
02520 gsaux = gL23[1] + gL23[2] * ksis + gL23[3] * ksis2 + gL23[4] * ksis3;
02521 gsaux += gL23[5] * ksis4 + gL23[6] * ksis5 + gL23[7] * ksis6 +
02522 gL23[8] * ksis7;
02523 gsaux += gL23[9] * ksis8;
02524 gsaux2 = 1 + ksis;
02525 gsaux2 *= gsaux2 * gsaux2;
02526 gsaux2 *= gsaux2 * gsaux2;
02527 gsaux2 *= 1 + ksis;
02528 gsaux /= gsaux2;
02529 }
02530 break;
02531 default:break;
02532 }
02533 return (gsaux);
02534 }
02535
02536
02537
02538
02539
02540
02541
02542
02543
02544
02545
02546
02547
02548
02549
02550 double ReisX_hs(FwTipo T, int SS, double ksih, double thet)
02551 {
02552 static double IhsC[6] = { 0.031, 0.031, 0.210, 0.005, -0.069, 0.324 };
02553 double x, x12, ksih3;
02554 double Ihs = 0.0, cs = 0.0;
02555 int n2hs = 0;
02556
02557 switch (T) {
02558
02559 case K:
02560 n2hs = 1;
02561 cs = 3.0 / 2.;
02562 break;
02563
02564 case L:
02565 n2hs = 2;
02566 if (SS == 1) cs = 3.0 / 2.;
02567 else cs = 5.0 / 4.;
02568 break;
02569
02570 default:break;
02571 }
02572 ksih3 = ksih * ksih * ksih;
02573 x = cs * n2hs / ksih;
02574 x12 = sqrt(x);
02575 if (x > 0 && x <= 0.035)
02576 Ihs = 3 * M_PI / 4 * log(1 / (x * x) - 1);
02577 if (x > 0.035 && x <= 3.1) {
02578 Ihs = IhsC[1] + IhsC[2] * x12 + IhsC[3] * x + IhsC[4] * x * x12 + IhsC[5] * x * x;
02579 Ihs = exp(-2 * x) / Ihs;
02580 }
02581 if (x > 3.1 && x < 11)
02582 Ihs = 2 * exp(-2 * x) / exp(1.6 * log(x));
02583
02584 return(n2hs * 2 * Ihs / (thet * ksih3));
02585 }
02586
02587
02588
02589
02590
02591
02592
02593
02594
02595
02596
02597
02598
02599 double ReisX_En(double z, int niu)
02600 {
02601
02602
02603 double Eaux, z2, z3, niu2, aux, aux2, aux4, aux6;
02604
02605 z2 = z * z;
02606 z3 = z2 * z;
02607 niu2 = niu * niu;
02608 aux = z + niu;
02609 aux2 = aux * aux;
02610 aux4 = aux2 * aux2;
02611 aux6 = aux4 * aux2;
02612 Eaux = niu * (6 * z2 - 8 * niu * z + niu2) / aux6;
02613 Eaux++;
02614 Eaux = exp(-z) * Eaux / aux;
02615 return(Eaux);
02616 }
02617
02618
02619
02620
02621
02622
02623
02624
02625
02626
02627
02628
02629
02630
02631 double ReisX_polisec(int ssind, double kz, double tz)
02632 {
02633 double Result = 0.0;
02634
02635 static double fc1[8] = {
02636 737.658767, -5422.24598, 17070.7835, -29572.7846,
02637 30490.2736, -18719.3387, 6343.25887, -916.108807
02638 };
02639
02640 static double fc2[8] = {
02641 -1513.63296, 5152.69169, -7347.41315, 5748.20489,
02642 -2665.54100, 733.610039, -111.064039, 7.14045527
02643 };
02644
02645 static double fc3[8] = {
02646 13.1119073, -41.7263393, 97.1163461, -100.159645,
02647 60.9662790, -21.6315896, 4.12048128, -0.325361134
02648 };
02649
02650 static double fc4[8] = {
02651 18.9172599, -59.1559460, 126.801210, -127.067875,
02652 74.6217068, -25.5046721, 4.68627281, -0.357639954
02653 };
02654
02655 double p1;
02656 double x = 0.0;
02657 double coef[8];
02658 int i;
02659
02660 switch (ssind) {
02661
02662 case 1:
02663 x = 1 / sqrt(kz * exp(0.3 * log(tz)));
02664 if (x < 1.35)
02665 memcpy(coef, fc1, sizeof(double) * 8);
02666 else
02667 memcpy(coef, fc2, sizeof(double) * 8);
02668 break;
02669
02670 case 2:
02671 x = 1 / sqrt(kz * exp(0.2 * log(tz)));
02672 memcpy(coef, fc3, sizeof(double) * 8);
02673 break;
02674
02675 case 3:
02676 x = 1 / sqrt(kz * exp(0.32 * log(tz)));
02677 memcpy(coef, fc4, sizeof(double) * 8);
02678 break;
02679 }
02680
02681 for (p1 = coef[7], i = 6; i >=0; i--) p1 = x * p1 + coef[i];
02682
02683 switch (ssind) {
02684
02685 case 1:
02686 Result = exp(-p1) / exp(3.8 * log(tz));
02687 break;
02688
02689 case 2:
02690 Result = exp(-p1) / exp(2.5 * log(tz));
02691 break;
02692
02693 case 3:
02694 Result = exp(-p1) / exp(6.5 * log(tz));
02695 break;
02696 }
02697 return(Result);
02698 }
02699
02700
02701
02702
02703
02704
02705
02706
02707
02708
02709
02710
02711
02712 double ReisX_g(int ss, atomicnumber Zg, double xi)
02713 {
02714 static double g3pol[2][8] = {
02715 { 4.980374404, -18.84795179, 37.53135546, -39.83029409, 23.94060788,
02716 -8.048533664, 1.397129084, -0.09706728869 },
02717 { -1.859600742, 12.30009972, -21.67920610, 20.38505540, -11.17032345,
02718 3.604521250, -0.6347055945, 0.04676377726 }
02719 };
02720
02721 static double g12pol[2][8] = {
02722 { 0.7800031227, 0.5779760376, 0.01209015664, 1.382072250, -2.555731314,
02723 1.534786106, -0.3844825563, 0.03457310793 },
02724 { -4.910259919, 27.43184219, -50.44519949, 48.46725025, -26.40954176,
02725 8.230146858, -1.365807669, 0.09332547710 }
02726 };
02727
02728 int i;
02729 int polsel = 0;
02730 double gaux = 0.0;
02731
02732 if (xi < 0.6 || xi > 2.6)
02733 return(1.0);
02734 else {
02735 if (ss == 3) {
02736 if (Zg < 47) return(1.0);
02737
02738 if (Zg < 64) polsel = 0;
02739 else polsel = 1;
02740
02741 for (gaux = g3pol[polsel][7],i = 6; i >= 0; i--) gaux = gaux * xi + g3pol[polsel][i];
02742 return(gaux);
02743 }
02744 if (ss == 1) {
02745 if (Zg > 61 && Zg < 72) polsel = 0;
02746 else return(1.0);
02747 }
02748 if (ss == 2) {
02749 if (Zg > 54 && Zg < 75) polsel = 1;
02750 else return(1.0);
02751 }
02752
02753 for (gaux = g12pol[polsel][7], i = 6; i >= 0; i--) gaux = gaux * xi + g12pol[polsel][i];
02754 return(gaux);
02755 }
02756 }
02757
02758
02759
02760
02761
02762
02763
02764
02765
02766
02767
02768
02769
02770
02771
02772
02773
02774
02775
02776
02777
02778
02779
02780
02781
02782 void PenInteg(atomicnumber atnumb, const CalibYld *AbsFac, const ESxType *ESA,
02783 const CalibYld *YldA, const CalibYld *TrsA, const CalibYld *pTrs0,
02784 int FExlen, int NeedSFC, int AllowXEqCalc,
02785 double x0, double CosInc,
02786 CalibYld *XYld, CalibYld *XSFCr, CalibYld *XYldxmed)
02787 {
02788 int i, j, l, limit;
02789 double auxfa, auxfb, auxfi, diffl;
02790 CalibYld auxxmed, auxy2;
02791 const CalibYld *pTrs1, *pYld1, *pSFC1, *pTrs2, *pYld2, *pSFC2, *pTrs3, *pYld3, *pSFC3;
02792
02793 const ESxType *pEF1, *pEF2, *pEF3;
02794
02795
02796
02797
02798
02799
02800
02801
02802
02803
02804 *XYld=CYldNul;
02805
02806 if(AllowXEqCalc) auxxmed = CYldNul;
02807
02808
02809 if (NeedSFC) {
02810 fprintf(stderr,"\n Error: Secondary Fluorescence not implemented yet\n"); exit(1);
02811
02812
02813 auxy2 = CYldNul;
02814 }
02815 else {
02816 pSFC1=&CYldNul;
02817 pSFC2=&CYldNul;
02818 pSFC3=&CYldNul;
02819 }
02820
02821 pEF1=&ESA[0];
02822 pTrs1=&TrsA[0];
02823 pYld1=&YldA[0];
02824
02825
02826
02827 limit=FExlen-1;
02828 for(i=1 ; i<limit ; i+=2){
02829
02830 pEF2=&ESA[i];
02831 pTrs2=&TrsA[i];
02832 pYld2=&YldA[i];
02833
02834 pEF3=&ESA[i+1];
02835 pTrs3=&TrsA[i +1];
02836 pYld3=&YldA[i +1];
02837
02838 if (atnumb < maxK) {
02839 for (j = 1; j <= 3; j++) {
02840 if (AbsFac->K_[j] > 0. && pTrs2->K_[j] > 1e-5) {
02841
02842 auxfa = (pTrs1->K_[j] * pYld1->K_[j] + pSFC1->K_[j]) / pEF1->stpp;
02843 auxfi = (pTrs2->K_[j] * pYld2->K_[j] + pSFC2->K_[j]) / pEF2->stpp;
02844 auxfb = (pTrs3->K_[j] * pYld3->K_[j] + pSFC3->K_[j]) / pEF3->stpp;
02845 XYld->K_[j] -= pTrs0->K_[j] * Simps(pEF1->ep, pEF3->ep, auxfa, auxfi, auxfb);
02846 #if CPIXEVERBOSITY > 1
02847 if(j==1) printf("\n Z=%d XYld=%le (XYld/Dx=%le) x1=%le ",
02848 atnumb, pTrs0->K_[j] *
02849 Simps(pEF1->ep, pEF3->ep, auxfa, auxfi, auxfb),
02850 Simps(pEF1->ep, pEF3->ep, auxfa, auxfi, auxfb)/(pEF1->x - pEF3->x),
02851 pEF1->x);
02852 #endif
02853
02854 if (AllowXEqCalc) {
02855 auxfa = (pTrs1->K_[j] * pYld1->K_[j] + pSFC1->K_[j]) * (pEF1->x + x0) * CosInc / pEF1->stpp;
02856 auxfi = (pTrs2->K_[j] * pYld2->K_[j] + pSFC2->K_[j]) * (pEF2->x + x0) * CosInc / pEF2->stpp;
02857 auxfb = (pTrs3->K_[j] * pYld3->K_[j] + pSFC3->K_[j]) * (pEF3->x + x0) * CosInc / pEF3->stpp;
02858 auxxmed.K_[j] -= pTrs0->K_[j] * Simps(pEF1->ep, pEF3->ep, auxfa, auxfi, auxfb);
02859 }
02860 if (NeedSFC){
02861 auxfa = pSFC1->K_[j] / pEF1->stpp;
02862 auxfi = pSFC2->K_[j] / pEF2->stpp;
02863 auxfb = pSFC3->K_[j] / pEF3->stpp;
02864 auxy2.K_[j] -= pTrs0->K_[j] * Simps(pEF1->ep, pEF3->ep, auxfa, auxfi, auxfb);
02865 }
02866 }
02867 }
02868 }
02869 if (atnumb > minM) {
02870 for (j = 1; j <= 3; j++) {
02871 if (AbsFac->M_[j] > 0. && pTrs2->M_[j] > 1e-5) {
02872 auxfa = (pTrs1->M_[j] * pYld1->M_[j] + pSFC1->M_[j]) / pEF1->stpp;
02873 auxfi = (pTrs2->M_[j] * pYld2->M_[j] + pSFC2->M_[j]) / pEF2->stpp;
02874 auxfb = (pTrs3->M_[j] * pYld3->M_[j] + pSFC3->M_[j]) / pEF3->stpp;
02875 XYld->M_[j] -= pTrs0->M_[j] * Simps(pEF1->ep, pEF3->ep, auxfa, auxfi, auxfb);
02876 if (AllowXEqCalc) {
02877 auxfa = (pTrs1->M_[j] * pYld1->M_[j] + pSFC1->M_[j]) * (pEF1->x + x0) * CosInc / pEF1->stpp;
02878 auxfi = (pTrs2->M_[j] * pYld2->M_[j] + pSFC2->M_[j]) * (pEF2->x + x0) * CosInc / pEF2->stpp;
02879 auxfb = (pTrs3->M_[j] * pYld3->M_[j] + pSFC3->M_[j]) * (pEF3->x + x0) * CosInc / pEF3->stpp;
02880 auxxmed.M_[j] -= pTrs0->M_[j] * Simps(pEF1->ep, pEF3->ep, auxfa, auxfi, auxfb);
02881 }
02882 if (NeedSFC){
02883 auxfa = pSFC1->M_[j] / pEF1->stpp;
02884 auxfb = pSFC2->M_[j] / pEF2->stpp;
02885 auxy2.M_[j] -= pTrs0->M_[j] * Simps(pEF1->ep, pEF3->ep, auxfa, auxfi, auxfb);
02886 }
02887 }
02888 }
02889 }
02890 if (atnumb > minL) {
02891 for (j = 1; j <= 3; j++) {
02892 for (l = 1; l <= 3; l++) {
02893 if (AbsFac->L_[j][l] > 0. && pTrs2->L_[j][l] > 1e-5) {
02894 auxfa = (pTrs1->L_[j][l] * pYld1->L_[j][l] + pSFC1->L_[j][l]) / pEF1->stpp;
02895 auxfi = (pTrs2->L_[j][l] * pYld2->L_[j][l] + pSFC2->L_[j][l]) / pEF2->stpp;
02896 auxfb = (pTrs3->L_[j][l] * pYld3->L_[j][l] + pSFC3->L_[j][l]) / pEF3->stpp;
02897 XYld->L_[j][l] -= pTrs0->L_[j][l] * Simps(pEF1->ep, pEF3->ep, auxfa, auxfi, auxfb);
02898 if (AllowXEqCalc) {
02899 auxfa = (pTrs1->L_[j][l] * pYld1->L_[j][l] + pSFC1->L_[j][l]) * (pEF1->x + x0) * CosInc / pEF1->stpp;
02900 auxfi = (pTrs2->L_[j][l] * pYld2->L_[j][l] + pSFC2->L_[j][l]) * (pEF2->x + x0) * CosInc / pEF2->stpp;
02901 auxfb = (pTrs3->L_[j][l] * pYld3->L_[j][l] + pSFC3->L_[j][l]) * (pEF3->x + x0) * CosInc / pEF3->stpp;
02902 auxxmed.L_[j][l] -= pTrs0->L_[j][l] * Simps(pEF1->ep, pEF3->ep, auxfa, auxfi, auxfb);
02903 }
02904 if (NeedSFC){
02905 auxfa = pSFC1->L_[j][l] / pEF1->stpp;
02906 auxfi = pSFC2->L_[j][l] / pEF2->stpp;
02907 auxfb = pSFC3->L_[j][l] / pEF3->stpp;
02908 diffl = 0.0;
02909 auxy2.L_[j][l] -= pTrs0->L_[j][l] * Simps(pEF1->ep, pEF3->ep, auxfa, auxfi, auxfb);
02910 }
02911 }
02912 }
02913 }
02914 }
02915 pYld1 = pYld3;
02916 pTrs1 = pTrs3;
02917 pEF1 = pEF3;
02918 pSFC1 = pSFC3;
02919 }
02920
02921 if (NeedSFC) {
02922 for (i = 1; i <= 3; i++) {
02923 if (XYld->K_[i] > 0.) XSFCr->K_[i] = auxy2.K_[i] / XYld->K_[i];
02924 if (XYld->M_[i] > 0.) XSFCr->M_[i] = auxy2.M_[i] / XYld->M_[i];
02925 for (j = 1; j <= 3; j++) {
02926 if (XYld->L_[i][j] > 0.) XSFCr->L_[i][j] = auxy2.L_[i][j] / XYld->L_[i][j];
02927 }
02928 }
02929 }
02930 else *XSFCr = CYldNul;
02931
02932 if (AllowXEqCalc) {
02933 for (i = 1; i <= 3; i++) {
02934 if (XYld->K_[i] > 0.) XYldxmed->K_[i] = auxxmed.K_[i] / XYld->K_[i];
02935 if (XYld->M_[i] > 0.) XYldxmed->M_[i] = auxxmed.M_[i] / XYld->M_[i];
02936 for (j = 1; j <= 3; j++) {
02937 if (XYld->L_[i][j] > 0.) XYldxmed->L_[i][j] = auxxmed.L_[i][j] / XYld->L_[i][j];
02938 }
02939 }
02940 }
02941
02942
02943 }
02944
02945
02946
02947
02948
02949
02950
02951
02952
02953
02954
02955
02956
02957
02958
02959
02960
02961
02962
02963
02964 double Simps(double a, double b, double fa, double fi, double fb)
02965 {
02966
02967 return ((b - a) / 6. * (fa + 4. * fi + fb));
02968 }
02969
02970
02971
02972
02973
02974
02975
02976
02977
02978
02979
02980
02981
02982
02983
02984
02985
02986
02987
02988
02989
02990
02991
02992
02993
02994
02995 void deNormalize(const EXP_PARAM *pexp, const AbsCoef *AbsC, const FluorCKCoef *pFCK, atomicnumber Z2, double M2, double attfraction, const CalibYld *pXYld, XrayYield *ResY, CalibYld *XYldSum)
02996 {
02997 double aux1;
02998 long jj, ll;
02999 CalibYld TransFact, Xaux;
03000 const SIM_PARAM *psim;
03001
03002 psim=&pexp->simpar;
03003
03004
03005 if (psim->useFilter){
03006
03007 fprintf(stderr,"\n Error: Filters not implemented yet\n"); exit(1);
03008
03009
03010
03011
03012
03013
03014
03015
03016
03017 }
03018 else{
03019 for (jj = 1; jj <= 3; jj++) {
03020 TransFact.K_[jj] = 1.0;
03021 TransFact.M_[jj] = 1.0;
03022 }
03023 for (jj = 1; jj <= 3; jj++) {
03024 for (ll = 1; ll <= 3; ll++) TransFact.L_[jj][ll] = 1.0;
03025 }
03026 }
03027
03028 Xprod(AbsC, pFCK, pexp->ion.Z, Z2, M2, psim->CalEner, &Xaux);
03029
03030 switch (ResY->atnum) {
03031
03032 case 10:
03033 case 11:
03034 case 12:
03035 case 13:
03036 case 14:
03037 if (Xaux.K_[1] > 0) {
03038 aux1 = ResY->XYld.K_[1] / Xaux.K_[1];
03039 ResY->XYld.K_[1] = pXYld->K_[1] * aux1 * psim->ColCharge * pexp->DetColFac *
03040 TransFact.K_[1] * psim->DTCC * attfraction;
03041 XYldSum->K_[1] +=ResY->XYld.K_[1];
03042 }
03043 break;
03044
03045 case 54:
03046 case 55:
03047 case 56:
03048 case 57:
03049 case 58:
03050 case 59:
03051 for (jj = 1; jj <= 3; jj++) {
03052 for (ll = 1; ll <= 3; ll++) {
03053 if (Xaux.L_[jj][ll] > 0){
03054 ResY->XYld.L_[jj][ll] = pXYld->L_[jj][ll] * (ResY->XYld.L_[jj][ll] / Xaux.L_[jj][ll]) *
03055 psim->ColCharge * pexp->DetColFac * TransFact.L_[jj][ll] *
03056 psim->DTCC * attfraction;
03057 XYldSum->L_[jj][ll] += ResY->XYld.L_[jj][ll];
03058 }
03059 }
03060 }
03061 break;
03062
03063 default:
03064 if (ResY->atnum >= 15 && ResY->atnum <minL) {
03065 for (jj = 1; jj <= 2; jj++) {
03066 if (Xaux.K_[jj] > 0) {
03067 aux1 = ResY->XYld.K_[jj] / Xaux.K_[jj];
03068 ResY->XYld.K_[jj] = pXYld->K_[jj] * aux1 * psim->ColCharge *
03069 pexp->DetColFac * TransFact.K_[jj] * psim->DTCC * attfraction;
03070 XYldSum->K_[jj] +=ResY->XYld.K_[jj];
03071 }
03072 }
03073 }
03074 else if (ResY->atnum >= minL && ResY->atnum < maxK) {
03075 for (jj = 1; jj <= 3; jj++) {
03076 if (Xaux.K_[jj] > 0) {
03077 aux1 = ResY->XYld.K_[jj] / Xaux.K_[jj];
03078 ResY->XYld.K_[jj] = pXYld->K_[jj] * aux1 * psim->ColCharge *
03079 pexp->DetColFac * TransFact.K_[jj] * psim->DTCC * attfraction;
03080 XYldSum->K_[jj] +=ResY->XYld.K_[jj];
03081 }
03082 }
03083 for (jj = 1; jj <= 3; jj++) {
03084 for (ll = 1; ll <= 3; ll++) {
03085 if (Xaux.L_[jj][ll] > 0){
03086 ResY->XYld.L_[jj][ll] = pXYld->L_[jj][ll] * (ResY->XYld.L_[jj][ll] / Xaux.L_[jj][ll]) *
03087 psim->ColCharge * pexp->DetColFac * TransFact.L_[jj][ll] *
03088 psim->DTCC * attfraction;
03089 XYldSum->L_[jj][ll] +=ResY->XYld.L_[jj][ll];
03090 }
03091 }
03092 }
03093 }
03094 else if (ResY->atnum >= minM && ResY->atnum <= 99) {
03095 for (jj = 1; jj <= 3; jj++) {
03096 for (ll = 1; ll <= 3; ll++) {
03097 if (Xaux.L_[jj][ll] > 0){
03098 ResY->XYld.L_[jj][ll] = pXYld->L_[jj][ll] * (ResY->XYld.L_[jj][ll] / Xaux.L_[jj][ll]) *
03099 psim->ColCharge * pexp->DetColFac * TransFact.L_[jj][ll] *
03100 psim->DTCC * attfraction;
03101 XYldSum->L_[jj][ll] +=ResY->XYld.L_[jj][ll];
03102 }
03103 }
03104 }
03105
03106 }
03107 break;
03108 }
03109 }
03110
03111
03112
03113
03114
03115
03116
03117
03118
03119
03120
03121
03122 void freeFilter(FILTER *Filter)
03123 {
03124 int i;
03125 foil *pFoil;
03126
03127 for(i=0 ; i < Filter->nlyr ; i++){
03128 pFoil=&Filter->foil[i];
03129 safefree((void*)(&pFoil->comp.elem));
03130 safefree((void*)(&pFoil->comp.X));
03131 safefree((void*)(&pFoil->comp.xn));
03132 safefree((void*)(&pFoil->comp.w));
03133
03134 }
03135 safefree((void*)(&Filter->FilterElems));
03136 safefree((void*)(&Filter->foil));
03137 safefree((void*)(&Filter->Trans));
03138
03139 }
03140
03141
03142
03143
03144
03145
03146
03147
03148 void freeReusable(int NFoils, LYR **plyrarray, foil **MatArray, CalibYld **XYldSums)
03149 {
03150 int i;
03151 LYR *plyr;
03152 foil *pMat;
03153
03154
03155 for(i=1;i<=NFoils;i++){
03156 plyr=&(*plyrarray)[i];
03157 safefree((void*)(&plyr->TrcAtnum));
03158 safefree((void*)(&plyr->Trans));
03159
03160 safefree((void*)(&plyr->ResYldArray));
03161 safefree((void*)(&plyr->SecResArray));
03162 safefree((void*)(&plyr->TrcUse));
03163 safefree((void*)(&plyr->NeedSFC));
03164 safefree((void*)(&plyr->ESxArray));
03165 safefree((void*)(&plyr->SSTrsArray));
03166 safefree((void*)(&plyr->SSYldArray));
03167
03168
03169 pMat=&(*MatArray)[i-1];
03170 safefree((void*)(&pMat->comp.elem));
03171 safefree((void*)(&pMat->comp.X));
03172 safefree((void*)(&pMat->comp.xn));
03173 safefree((void*)(&pMat->comp.w));
03174
03175 }
03176 safefree((void*)plyrarray);
03177
03178 safefree((void*)MatArray);
03179
03180 safefree((void*)XYldSums);
03181 }
03182
03183
03184
03185
03186
03187
03188 void safefree(void **ptr){
03189 if(*ptr!=NULL){
03190
03191 free(*ptr);
03192
03193 *ptr=NULL;
03194 }
03195 }
03196
03197
03198
03199
03200
03201
03202
03203 void fprintCALIBYLD(FILE *f,const CalibYld *pCYld)
03204 {
03205 int j,l;
03206 for (j = 1; j <= 3; j++) fprintf(f,"\t%le",pCYld->K_[j]);
03207 for (j = 1; j <= 3; j++) {
03208 fprintf(f,"\n");
03209 for (l = 1; l <= 3; l++)fprintf(f,"\t%le",pCYld->L_[j][l]);
03210 }
03211 fprintf(f,"\n");
03212 for (j = 1; j <= 3; j++) fprintf(f,"\t%le",pCYld->M_[j]);
03213
03214 fprintf(f,"\n");
03215 }
03216
03217
03218
03219
03220
03221
03222 void fscanCALIBYLD(FILE *f, CalibYld *pCYld)
03223 {
03224 int j,l;
03225 for (j = 1; j <= 3; j++) fscanf(f,"%lf",&pCYld->K_[j]);
03226 for (j = 1; j <= 3; j++) {
03227 for (l = 1; l <= 3; l++)fscanf(f,"%lf",&pCYld->L_[j][l]);
03228 }
03229 for (j = 1; j <= 3; j++) fscanf(f,"%lf",&pCYld->M_[j]);
03230
03231 }
03232