00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <stdio.h>
00021 #include <math.h>
00022 #include <string.h>
00023 #include <stdlib.h>
00024 #include "libcpixe.h"
00025 #include "compilopt.h"
00026
00027
00035 int createSFCList(const EXP_PARAM *pexp, const int *PresentElems, const XrayYield *XYldArray, const AbsCoef *TotAbsCoefArray, int *nSFCList, SFCListElem **SFCList)
00036 {
00037 int Za,Zb;
00038 int dim;
00039
00040 *nSFCList=0;
00041 *SFCList=NULL;
00042
00043 dim=pexp->simpar.MaxZinsample+1;
00044
00045 for(Zb=minK;Zb<dim;Zb++){
00046 if(PresentElems[Zb]){
00047 for(Za=minK;Za<dim;Za++){
00048 if(PresentElems[Za]){
00049 needSFC(Za, Zb, &XYldArray[Za].ener, &TotAbsCoefArray[Zb], nSFCList, SFCList);
00050 }
00051 }
00052 }
00053 }
00054 return(0);
00055 }
00056
00057 int needSFC(atomicnumber Za, atomicnumber Zb, const CalibYld *enerA, const AbsCoef *AbsC, int *nSFCList, SFCListElem **SFCList )
00058 {
00059 int j,l,i,ib,nabs;
00060 int n;
00061 double enerB,enerB_K,enerB_LIII;
00062 SFCListElem tempList[135];
00063
00064 if(Za<minK || Zb <minK ) {
00065 return(0);
00066 }
00067
00068 nabs=4;
00069
00070 if(Zb<minL)nabs=1;
00071
00072 enerB_K=AbsC->enr[0];
00073 if(enerB_K<0.001)enerB_K=HUGE;
00074 enerB_LIII=AbsC->enr[4];
00075 if(enerB_LIII<0.001)enerB_LIII=HUGE;
00076
00077
00078 for (n=0, ib=1;ib<=nabs;ib++){
00079 enerB=AbsC->enr[ib];
00080 if(enerB>0){
00081
00082 for (j = 1; j <= 3; j++) {
00083 if(enerA->K_[j]>enerB){
00084 tempList[n].Za=Za;
00085 tempList[n].Zb=Zb;
00086 tempList[n].epri=0;
00087 tempList[n].esec=j;
00088 tempList[n].abs=ib;
00089 tempList[n].Ea=enerA->K_[j];
00090 tempList[n].sigmaphoto=sigmaphoto(ib, AbsC, Zb, enerA->K_[j]);
00091 n++;
00092 }
00093 }
00094
00095 if(Za>minL) for (j = 1; j <= 3 ; j++) for (l = 1; l <= 3; l++) {
00096 if(inrange(enerA->L_[j][l],enerB,enerB_K)) {
00097 tempList[n].Za=Za;
00098 tempList[n].Zb=Zb;
00099 tempList[n].epri=j;
00100 tempList[n].esec=l;
00101 tempList[n].abs=ib;
00102 tempList[n].Ea=enerA->L_[j][l];
00103 tempList[n].sigmaphoto=sigmaphoto(ib, AbsC, Zb, enerA->L_[j][l]);
00104 n++;
00105 }
00106 }
00107
00109 if(Za>minM) for (j = 1; j <= 3; j++) {
00110 if(inrange(enerA->M_[j],enerB,enerB_LIII) ) {
00111 tempList[n].Za=Za;
00112 tempList[n].Zb=Zb;
00113 tempList[n].epri=4;
00114 tempList[n].esec=j;
00115 tempList[n].abs=ib;
00116 tempList[n].Ea=enerA->M_[j];
00117 tempList[n].sigmaphoto=sigmaphoto(ib, AbsC, Zb, enerA->M_[j]);
00118 n++;
00119 }
00120 }
00121 }
00122 }
00123
00124
00125 if(n>0){
00126 *SFCList =(SFCListElem*)realloc(*SFCList, (*nSFCList + n)*sizeof(SFCListElem));
00127 if (*SFCList==NULL){fprintf(stderr,"\n Error allocating memory (SFCList)\n");exit(1);}
00128 }
00129 for(i=0;i<n;i++)(*SFCList)[*nSFCList+i]=tempList[i];
00130
00131 *nSFCList+=n;
00132
00133 return(n);
00134 }
00135
00136
00137 double sigmaphoto(int iabs, const AbsCoef *AbsC, atomicnumber Zb, double Xray)
00138 {
00139 double result;
00140 double abs;
00141 int iener;
00142 int i;
00143 double stdener[23] = { 1.00, 1.25, 1.50, 1.75, 2.00,
00144 2.50, 3.00, 3.50, 4.00, 4.50, 5.00,
00145 5.50, 6.00, 6.50, 7.00, 8.00, 10.0,
00146 12.5, 15.0, 17.5, 20.0, 25.0, 30.0};
00147
00148 i=iabs-1;
00149
00150
00151
00152 switch(iabs){
00153 case 1:
00154 result=( 1.-AbsC->coefenr[0][0]/AbsC->coefenr[0][1] );
00155 break;
00156 case 2:
00157 result=( 1. - AbsC->coefenr[1][0]/AbsC->coefenr[1][1] );
00158 break;
00159 case 3:
00160 result=( 1.-AbsC->coefenr[2][0]/AbsC->coefenr[2][1] );
00161 if(Xray > AbsC->enr[2]) result*= AbsC->coefenr[1][0]/AbsC->coefenr[1][1];
00162 break;
00163 case 4:
00164 result=( 1.-AbsC->coefenr[3][0]/AbsC->coefenr[3][1] );
00165 if(Xray > AbsC->enr[3]) result*= AbsC->coefenr[2][0]/AbsC->coefenr[2][1];
00166 if(Xray > AbsC->enr[2]) result*= AbsC->coefenr[1][0]/AbsC->coefenr[1][1];
00167 break;
00168 case 5:
00169 case 6:
00170 case 7:
00171 case 8:
00172 case 9:
00173 result=( 1.-AbsC->coefenr[4][0]/AbsC->coefenr[i][1] );
00174 break;
00175 }
00176
00177
00178 for(iener=1;Xray > stdener[iener];iener++);
00179
00180
00181 abs=TotAbsor_elemental(iener, AbsC, Zb, Xray);
00182
00183
00184 return(result*abs);
00185 }
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00242 int inrange(double value,double min, double max)
00243 {
00244 if(value<min || value>max) return(0);
00245 else return(1);
00246 }
00247