Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

cpixe-calib.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2005 by Carlos Pascual-Izarra                           *
00003  *   carlos.pascual@itn.pt                                                 *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00019  ***************************************************************************/
00020  
00021  
00022  
00023 /**\file cpixe-calib.c
00024 cpixe-calib is an auxiliary program for creating the detector efficiency calibration files used by programs based on the LibCPIXE library.
00025 
00026 cpixe-calib uses also the LibCPIXE library
00027 
00028 See the libcpixe.c file for more information.
00029 
00030 */
00031 
00032 
00033 #ifdef HAVE_CONFIG_H
00034 #include <config.h>
00035 #endif
00036 
00037 #include <stdio.h>
00038 #include <stdlib.h>
00039 #include <math.h>
00040 #include <string.h>
00041 
00042 #include "libcpixe.h"
00043 #include "compilopt.h"
00044 
00045 int main(int argc, char *argv[]);
00046 int cpixecalib(void);
00047 
00048 STATFILENAME inputfilename="input-cal.in";
00049 
00050 /**Main program for cpixe-calib:
00051  * The executable accepts a list of command line arguments
00052  * indicating the input file names
00053  * If none is specified, ("input-cal.in" is assumed).
00054  *
00055  * @return EXIT_SUCCESS if normal finishing
00056  */
00057 int main(int argc, char *argv[])
00058 {
00059   int i;
00060   extern STATFILENAME inputfilename;  
00061   
00062   if(argc>1){
00063     for(i=1;i<argc;i++){
00064       strcpy(inputfilename,argv[i]);
00065       cpixecalib();
00066     }
00067   }
00068   else cpixecalib();
00069   
00070   return EXIT_SUCCESS;
00071 }
00072 
00073 /** Calculates the efficiency coefficient based on experimental data and 
00074  * (hopefully) accurate description of the sample.
00075  * The efficiency coefs have the following meaning:
00076  
00077  "Number of counts that are expected in the detector for a given X-ray emission line induced by a 2MeV proton beam in an ideally thin target, per unit of irradiation charge (uC), per unit of solid angle (msr) and per 10^15 at/cm2 of the element"
00078  
00079  * @return EXIT_SUCCESS if no error ocurred and "-1" if some error happened. 
00080  */
00081 int cpixecalib(void)
00082 {
00083   STATFILENAME dbpath="./";
00084   extern STATFILENAME inputfilename;
00085   STATFILENAME samplefilenm=""; 
00086   STATFILENAME filterfilenm=""; 
00087   STATFILENAME calibfilenm="";
00088   STATFILENAME areasfilenm="";
00089   STATFILENAME fckfilename="";
00090   STATFILENAME abscoeffilename=""; 
00091   STATFILENAME outputfilenm="";
00092   
00093   EXTRAINFO ExtraInfo;
00094   LYR *lyr;
00095   CalibYld *XYldSums;
00096   int i,j,l,Z;
00097   double tempM;
00098   EXP_PARAM *pExpPar;
00099   SIM_PARAM *pSimPar;
00100   CalibYld tempCYld,tempEff,tempRatio,tempXprodEcal;
00101   
00102    /*Static variables (Those that should be maintained between calls of CPIXEMAIN()*/
00103   static int *PresentElems;
00104   static CPIXERESULTS *CalcFlags;
00105   static XrayYield *XYldArray;
00106   static FluorCKCoef *FCKCoefArray;
00107   static AbsCoef *TotAbsCoefArray;
00108   static SPT *SPTArray;
00109   static FILTER Filter;
00110   
00111   static EXP_PARAM ExpPar;
00112   static foil *Sample;
00113   static int NFoil, NFoilUsed, dimSums;
00114   static FILE *outputfile;
00115   
00116   #if CPIXEVERBOSITY > 0
00117   printf("\n\n\n************ BEGIN OF CPIXE OUTPUT ****************\n\n");
00118   #endif
00119 
00120   pExpPar=&ExpPar;
00121   pSimPar=&pExpPar->simpar;
00122 
00123 
00124   /**********BEGIN INITIALIZATION*********/
00125 
00126   //initialize the file name pointers of the ExtraInfo structure
00127   ExtraInfo.SampleFileNm=samplefilenm;
00128   ExtraInfo.FilterFileNm=filterfilenm;
00129   ExtraInfo.XYldFileNm=calibfilenm;
00130   ExtraInfo.AreasFileNm=areasfilenm;
00131   ExtraInfo.DBpath=dbpath;
00132   ExtraInfo.OutputFileNm=outputfilenm;
00133 
00134   readINPUT(inputfilename, pExpPar, &ExtraInfo);
00135   //Check that a calibration is required
00136   
00137   //For calibration, areas with errors are needed:
00138   if(ExtraInfo.AreasFormat!=2){fprintf(stderr,"\nERROR: Areas + errors are needed for calibration (use DTAREASFILE instead of CALCFLAGS)\n");exit(1);}
00139   //also the "DoCalibration Flagg must be on
00140   if(!ExtraInfo.DoCalibration){fprintf(stderr,"\nERROR: The DoCalibration flag is not 1\n");exit(1);}
00141   
00142   readsample(samplefilenm, &pSimPar->MaxZinsample, &NFoil, &Sample);
00143   readFilter(filterfilenm, &Filter);
00144   //translate Filter definition     
00145   Filter.changes=1;    //First time at least Filter should be read:
00146   
00147   snprintf(fckfilename, FILENMLENGTH,"%sSC_PRA74.fck",dbpath);
00148   snprintf(abscoeffilename, FILENMLENGTH,"%sxabs.abs",dbpath); 
00149 
00150   #if CPIXEVERBOSITY > 0  
00151   printf("\nInitializing. Reading databases...\n\n");
00152   printf("\nStopping Coefs DB: '%sSCOEF.95[A/B]'",dbpath);
00153   printf("\nAbsorption Coefs DB: '%s'",abscoeffilename);
00154   printf("\nFluorescence Coefs DB: '%s'",fckfilename);
00155   printf("\nDetector Calibration DB: '%s'",calibfilenm);
00156   printf("\nLines to calculate defined in: '%s'\n",areasfilenm);
00157   #endif
00158 
00159   createPresentElems(pSimPar->MaxZinsample, NFoil, Sample, &PresentElems);
00160   readCalcFlags(areasfilenm, PresentElems, pSimPar->MaxZinsample, ExtraInfo.AreasFormat, &CalcFlags);
00161   
00162   #if CPIXEVERBOSITY > 0
00163   for(i=1;i<pSimPar->MaxZinsample+1;i++){
00164     if(PresentElems[i]){
00165       printf("\nZ=%d  (%d)\n ",i,CalcFlags[i].atnum);
00166       for (j = 1; j <= 3; j++) printf("\t%.0lf",CalcFlags[i].simareas.K_[j]);
00167       for (j = 1; j <= 3; j++) { 
00168         printf("\n");
00169         for (l = 1; l <= 3; l++)printf("\t%.0lf",CalcFlags[i].simareas.L_[j][l]);
00170       }
00171       printf("\n");
00172       for (j = 1; j <= 3; j++) printf("\t%.0lf",CalcFlags[i].simareas.M_[j]);
00173     }
00174   }
00175   #endif
00176 
00177   //Instead of reading a regular calib file, read a "fake one" containing all 1's
00178   snprintf(calibfilenm,FILENMLENGTH,"%sCALIB1.CAL",dbpath);
00179   readXYld(calibfilenm, PresentElems, CalcFlags, pSimPar->MaxZinsample, &pSimPar->CalEner, &XYldArray);  
00180   
00181   readFCK(fckfilename, pSimPar->MaxZinsample,&FCKCoefArray);
00182   readAbsCoef(abscoeffilename, pSimPar->MaxZinsample, PresentElems, &Filter, &TotAbsCoefArray);
00183   createSPTs(dbpath,pExpPar, pSimPar->MaxZinsample, PresentElems, (double)(2*pExpPar->ion.A), &SPTArray);
00184   
00185   /********** END INITIALIZATION *********/
00186 
00187     
00188 
00189   /******* BEGIN CALCULATION*********/
00190   
00191   //Calculate Filter Transmission if the filter changed
00192   if(Filter.changes){
00193     FilterTrans(pExpPar, XYldArray, TotAbsCoefArray, PresentElems, &Filter);
00194     ///@todo This indicates that the filter is not going to be varied (Provisional)
00195     Filter.changes=0;
00196   }
00197 
00198   initlyrarray(pExpPar, Sample, XYldArray, TotAbsCoefArray, SPTArray, PresentElems, NFoil, &NFoilUsed, &lyr);
00199   dimSums=pSimPar->MaxZinsample+1;
00200   XYldSums=(CalibYld*)calloc(dimSums,sizeof(CalibYld));  //Note that XYldSums is 0-initialized
00201   integrate_Simpson(pExpPar, TotAbsCoefArray, FCKCoefArray, XYldArray ,NFoilUsed, &Filter, lyr, XYldSums);
00202   
00203   
00204   
00205   ///@todo Divide the calib yields by Xprod(Ecal) to obtain detector efficiency at the given emission energy. Tabulate [emission_energy,efficiency] --->Output
00206   ///@todo the detector efficiency can be fitted VS energy. The fit can be interpolated and converted back to calib yields for the elements/lines for which no experimental info was available (i.e. construct the calib file) 
00207     /******END CALCULATION**********/
00208   
00209   /**********BEGIN FILE OUTPUT LINES*******/
00210   if(ExtraInfo.WantOutputfile){
00211     outputfile = fopen(outputfilenm, "w");
00212     if(outputfile== NULL)
00213       {fprintf(stderr,"\nERROR: Could not open file '%s' for write.\n",outputfilenm);exit(1);}
00214     
00215     fprintf(outputfile,"\n\nBEGIN_HEADER \n");
00216     //Write initialization parameters to output file
00217     
00218     fprintf(outputfile,"\nCPIXE-CALIB Output File\n\n");
00219     fprintf(outputfile,"\nStopping Coefs DB: '%sSCOEF.95[A/B]'",dbpath);
00220     fprintf(outputfile,"\nAbsorption Coefs DB: '%s'",abscoeffilename);
00221     fprintf(outputfile,"\nFluorescence Coefs DB: '%s'",fckfilename);
00222     fprintf(outputfile,"\nFake Detector Calibration DB: '%s'",calibfilenm);
00223     fprintf(outputfile,"\nExperimental Areas read from: '%s'\n",areasfilenm);
00224   
00225 
00226     fprintf(outputfile,"\n\nKEV      \t%lg\nINCANG   \t%lg\nEXITANG  \t%lg\n",
00227           pExpPar->BeamEner, pExpPar->IncAng/DEG2RAD, pExpPar->DetAng/DEG2RAD);
00228     fprintf(outputfile,"\nCHARGE   \t%lg\nDTCC     \t%lg\nDETCOLFAC \t%lg\n",
00229           pExpPar->simpar.ColCharge, pExpPar->simpar.DTCC, pExpPar->DetColFac);
00230     fprintf(outputfile,"\n\nCALENER    \t%lg\n", pExpPar->simpar.CalEner);
00231     
00232     for(i=0;i<NFoil;i++){
00233       fprintf(outputfile,"\nSample[%d]  (%d elem)\n",i,Sample[i].nfoilelm);
00234       fprintf(outputfile,"\n---Eff. thickness=%.3le  (%d sublyrs)\n",lyr[i+1].ThickIn,lyr[i+1].FESxlen);
00235       
00236       for(j=0;j<Sample[i].comp.nelem;j++){
00237       fprintf(outputfile,"'%s'(Z=%d) X[%d]=%lf (%lfat%% / %lfM%%)\n",
00238           XYldArray[Sample[i].comp.elem[j].Z].symb,Sample[i].comp.elem[j].Z,j,Sample[i].comp.X[j],100*Sample[i].comp.xn[j],100*Sample[i].comp.w[j]);
00239       }
00240       fprintf(outputfile,"\nFinal Energy in this layer=%lf keV\n\n",lyr[i+1].FoilOutEner);
00241     }
00242   
00243     for(i=0;i<Filter.nlyr;i++){
00244       fprintf(outputfile,"\nFilter[%d] (%lf 1e15at/cm2)  (%d elem)  \n",i,Filter.foil[i].thick,Filter.foil[i].nfoilelm);
00245       for(j=0;j<Filter.foil[i].comp.nelem;j++){
00246       fprintf(outputfile,"(Z=%d) X[%d]=%lf (%lfat%% / %lfM%%)\n",
00247           Filter.foil[i].comp.elem[j].Z,j,Filter.foil[i].comp.X[j],100*Filter.foil[i].comp.xn[j],100*Filter.foil[i].comp.w[j]);
00248       }
00249     }
00250     
00251     fprintf(outputfile,
00252     "Datablocks Format: \n\
00253     Atnumb\n\
00254     \t{emission energies}\n\
00255     \t{CalibYlds}\n\
00256     \t{Detector efficiencies}\n\
00257     \t{Yield Ratios}");
00258 
00259     fprintf(outputfile,"\n\nEND_HEADER \n");
00260     fprintf(outputfile,"\n\nDATA \n");
00261     
00262     for(Z=1;Z<pSimPar->MaxZinsample+1;Z++){
00263       if(PresentElems[Z]){
00264         Z2mass(Z, &tempM, 'n');
00265         Xprod(&TotAbsCoefArray[Z], &FCKCoefArray[Z], pExpPar->ion.Z, Z, tempM , pExpPar->simpar.CalEner, &tempXprodEcal);
00266         
00267         //calculate Calibration Yields (referred to Ecal), Detector efficiencies and Line ratios
00268         for (j = 1; j <= 3; j++)
00269           if (XYldSums[Z].K_[j]>0){
00270             tempCYld.K_[j]=CalcFlags[Z].simareas.K_[j]/XYldSums[Z].K_[j]; 
00271             tempEff.K_[j]=tempCYld.K_[j]/tempXprodEcal.K_[j];
00272             tempRatio.K_[j]=tempCYld.K_[j]/tempCYld.K_[1];
00273           }
00274           else{
00275            tempCYld.K_[j]=0;
00276            tempEff.K_[j]=0;
00277            tempRatio.K_[j]=0;
00278           }
00279         for (j = 1; j <= 3; j++) { 
00280           for (l = 1; l <= 3; l++) 
00281             if (XYldSums[Z].L_[j][l]>0){
00282               tempCYld.L_[j][l]=CalcFlags[Z].simareas.L_[j][l]/XYldSums[Z].L_[j][l];
00283               tempEff.L_[j][l]=tempCYld.L_[j][l]/tempXprodEcal.L_[j][l];
00284               tempRatio.L_[j][l]=tempCYld.L_[j][l]/tempCYld.L_[j][1];
00285             }
00286             else{
00287            tempCYld.L_[j][l]=0;
00288            tempEff.L_[j][l]=0;
00289            tempRatio.L_[j][l]=0;
00290           }
00291         }
00292         for (j = 1; j <= 3; j++) 
00293           if (XYldSums[Z].M_[j]>0){
00294             tempCYld.M_[j]=CalcFlags[Z].simareas.M_[j]/XYldSums[Z].M_[j];
00295             tempEff.M_[j]=tempCYld.M_[j]/tempXprodEcal.M_[j];
00296             tempRatio.M_[j]=tempCYld.M_[j]/tempCYld.M_[1];  
00297           }
00298           else {
00299            tempCYld.M_[j]=0;
00300            tempEff.M_[j]=0;
00301            tempRatio.M_[j]=0;
00302           }
00303         
00304         //Print results:
00305         fprintf(outputfile,"\n %d\n",CalcFlags[Z].atnum); //atomic number
00306         fprintCALIBYLD(outputfile,&XYldArray[Z].ener);    //emission energies
00307         fprintf(outputfile,"\n");       
00308         fprintCALIBYLD(outputfile,&tempCYld);             //Calibration Ylds (referred to Ecal)
00309         fprintf(outputfile,"\n");                         
00310         fprintCALIBYLD(outputfile,&tempEff);              //Detector efficiency
00311         fprintf(outputfile,"\n");                         
00312         fprintCALIBYLD(outputfile,&tempRatio);            //Yield ratios (referred to the main line)
00313         fprintf(outputfile,"\n");                         
00314         
00315         
00316         //Calculate and print 
00317       }
00318     }
00319   }
00320   /**********END FILE OUTPUT LINES*******/
00321    
00322       
00323   #if CPIXEVERBOSITY > 0  
00324   /**********BEGIN DEBUG LINES*******/
00325   /* Just write stuff for debugging*/
00326   printf("\n\n Ebeam=%lf IncAng=%lf  DetAng=%lf \n",
00327         pExpPar->BeamEner, pExpPar->IncAng/DEG2RAD, pExpPar->DetAng/DEG2RAD);
00328   printf("\n Charge=%lf   DTCC=%lf DetColFac=%lf\n",
00329         pExpPar->simpar.ColCharge, pExpPar->simpar.DTCC, pExpPar->DetColFac);
00330   printf("\n CalibEner=%lf\n", pExpPar->simpar.CalEner);
00331 
00332   for(i=0;i<NFoil;i++){
00333     printf("\nSample[%d]  (%d elem)\n",i,Sample[i].nfoilelm);
00334     printf("\n---Eff. thickness=%.3le  (%d sublyrs)\n",lyr[i+1].ThickIn,lyr[i+1].FESxlen);
00335     
00336     for(j=0;j<Sample[i].comp.nelem;j++){
00337     printf("'%s'(Z=%d) X[%d]=%lf (%lfat%% / %lfM%%)\n",
00338         XYldArray[Sample[i].comp.elem[j].Z].symb,Sample[i].comp.elem[j].Z,j,Sample[i].comp.X[j],100*Sample[i].comp.xn[j],100*Sample[i].comp.w[j]);
00339     }
00340     printf("\nFinal Energy in this layer=%lf keV\n\n",lyr[i+1].FoilOutEner);
00341   }
00342 
00343   for(i=0;i<Filter.nlyr;i++){
00344     printf("\nFilter[%d] (%lf 1e15at/cm2)  (%d elem)  \n",i,Filter.foil[i].thick,Filter.foil[i].nfoilelm);
00345     for(j=0;j<Filter.foil[i].comp.nelem;j++){
00346     printf("(Z=%d) X[%d]=%lf (%lfat%% / %lfM%%)\n",
00347         Filter.foil[i].comp.elem[j].Z,j,Filter.foil[i].comp.X[j],100*Filter.foil[i].comp.xn[j],100*Filter.foil[i].comp.w[j]);
00348     }
00349   }
00350   
00351   for(i=0;i<dimSums;i++){
00352     if(i<=pSimPar->MaxZinsample && PresentElems[i]){
00353       printf("\n\n ************RESULTS for %s (Z=%d)\n",XYldArray[i].symb,i);
00354       /*K lines:*/
00355       for (j = 1; j <= 3; j++) 
00356         if(XYldSums[i].K_[j] > 0.) 
00357           printf("\n%10s (%2.2lfkeV)\t%le counts @ %lgkeV   (calib=%le)", LineNm[1][j], XYldArray[i].ener.K_[j],CalcFlags[i].simareas.K_[j]/XYldSums[i].K_[j],pExpPar->simpar.CalEner,XYldArray[i].XYld.K_[j]);
00358       /*L-Lines*/
00359       for (j = 1; j <= 3; j++)
00360         for (l = 1; l <= 3; l++) 
00361           if(XYldSums[i].L_[j][l] > 0.)
00362             printf("\n%10s (%2.2lfkeV)\t%le counts @ %lgkeV  (calib=%le)", LineNm[j+1][l], XYldArray[i].ener.L_[j][l], CalcFlags[i].simareas.L_[j][l]/XYldSums[i].L_[j][l],pExpPar->simpar.CalEner,XYldArray[i].XYld.L_[j][l]); 
00363       /*M lines:*/
00364       for (j = 1; j <= 3; j++) 
00365         if(XYldSums[i].M_[j] > 0.) 
00366           printf("\n%10s (%2.2lfkeV)\t%le counts @ %lgkeV  (calib=%le)",LineNm[5][j], XYldArray[i].ener.M_[j], CalcFlags[i].simareas.M_[j]/XYldSums[i].M_[j],pExpPar->simpar.CalEner,XYldArray[i].XYld.M_[j]);
00367     }
00368   }
00369 
00370   /**********END DEBUG LINES*******/
00371   #endif  
00372   
00373    
00374   /*It is VERY important to call freeReusable() before starting a new iteration*/
00375   freeReusable(NFoil,&lyr,&Sample,&XYldSums);
00376   //    printf("\n!!!!!!! %d  %d",NCALL,Filter.changes);
00377   if(Filter.changes)freeFilter(&Filter);
00378   
00379    
00380   /******** BEGIN TIDING UP BEFORE FINAL EXIT*********/
00381   /*Free everything for a clean exit*/
00382   #if CPIXEVERBOSITY > 0  
00383   printf("\nCleaning CPIXE-CALIB Memory usage...\n\n");
00384   #endif
00385   
00386   //Note: Filter.changes=0 implies that freeFilter was not called in last iteration:
00387   if(!Filter.changes)freeFilter(&Filter);
00388   
00389   for(i=1; i<=pSimPar->MaxZinsample ;i++){
00390     if(PresentElems[i]){
00391       free(SPTArray[i].S);
00392       free(SPTArray[i].E);
00393       free(SPTArray[i].dSdE);
00394     }
00395   }
00396   free(SPTArray);
00397   free(PresentElems); 
00398   free(XYldArray);
00399   free(FCKCoefArray);
00400   free(TotAbsCoefArray);
00401   free(CalcFlags);
00402   /******** END TIDING UP BEFORE FINAL EXIT*********/
00403   
00404   
00405   if(ExtraInfo.WantOutputfile)fclose(outputfile);
00406 
00407   #if CPIXEVERBOSITY > 0
00408   printf("\n\n\n************ END OF CPIXE OUTPUT ****************\n\n");
00409   #endif
00410   
00411   return EXIT_SUCCESS;
00412 }
00413 
00414 
00415 
00416 
00417 

Generated on Fri Jul 15 20:43:49 2005 for LibCPIXE API by  doxygen 1.3.9.1