00001
00002
00003
00004
00005
00006
00007 #include "reconstruction/CalProfile.h"
00008
00009 #include "reconstruction/GlastRecon.h"
00010 #include "reconstruction/LbldData.h"
00011 #include "reconstruction/CalRecon.h"
00012 #include "reconstruction/TrackerRecon.h"
00013 #include "reconstruction/gamma.h"
00014 #include "reconstruction/ReconVisitor.h"
00015
00016 #include "data/GlastData.h"
00017
00018 #include "analysis/Midnight.h"
00019
00020 #include "DetectorData.h"
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 int nbins;
00032 std::vector<double> layer;
00033 std::vector<double> delta;
00034 double slope,size,radlen;
00035
00036 double fit_energy;
00037 double ki2;
00038 double fit_alpha;
00039 double fit_lambda;
00040 double fit_start;
00041 double energy_err;
00042 double alpha_err;
00043 double lambda_err;
00044 double start_err;
00045
00046
00047 static double gam_prof(double *par, int i)
00048 {
00049 double result =0;
00050
00051 double length = ((2.3*i+par[2])/1.85)/slope;
00052
00053
00054
00055
00056 double alpha = 2.65 * exp(0.15*log(par[0]));
00057 double lambda = 2.29 * exp(-0.031*log(par[0]));
00058
00059 double x=length/lambda;
00060 double dx = 2.3 / (1.85 *lambda)/slope;
00061
00062 double gamma1 =0;
00063 double gamma2 = 0;
00064
00065
00066
00067 gamma1 = Gamma(alpha,x);
00068 x += dx;
00069
00070 gamma2 = Gamma(alpha,x);
00071 result = par[0]*(gamma2 - gamma1);
00072
00073
00074 return result;
00075 }
00076
00077
00078
00079 static void fcn(int &npar, double *gin, double &f, double *par, int iflag)
00080 {
00081 int i;
00082
00083 double chisq = 0;
00084 double dlt;
00085 for (i=0;i<nbins; i++) {
00086 dlt = (layer[i]-gam_prof(par,i));
00087 if(layer[i]>0.0001) chisq += dlt*dlt/layer[i];
00088 }
00089 f = chisq;
00090
00091 }
00092
00093 void CalProfile::reconstruct(const GlastData* gdata)
00094 {
00095 if( eTotal==0 ) return;
00096
00097 nbins = static_cast<int>( num_layers );
00098 std::vector<double> E_layer = cal->Get_Elayer();
00099 layer.resize(num_layers);
00100
00101
00102
00103 for(int jlayer = 0; jlayer < num_layers; jlayer++) {
00104 int ilayer = static_cast<int>( num_layers-1 - jlayer );
00105 layer[jlayer] = E_layer[ilayer];
00106 }
00107
00108 delta.resize(num_layers);
00109
00110 slope = fabs(dirZ);
00111 radlen = 1.85;
00112 size = 1.96;
00113
00114
00115 float vstrt[5];
00116 float stp[5];
00117 float bmin[5];
00118 float bmax[5];
00119
00120
00121
00122
00123
00124
00125 vstrt[0] = eTotal;
00126 if(eTotal>0.0001) vstrt[1] = 2.65 * exp(0.15*log(eTotal));
00127 else vstrt[1]=0;
00128 vstrt[2] = 1.8f;
00129
00130 stp[0]=0.1f;
00131 stp[1]= 0.01f;
00132 stp[2] = 0.2f;
00133
00134 bmin[0] = eTotal;
00135 bmin[1] = 1;
00136 bmin[2] = 0.5;
00137
00138 bmax[0] = 5000;
00139 bmax[1] = 15;
00140 bmax[2] = 5;
00141
00142
00143 minuit = new Midnight(5);
00144
00145 minuit->SetFCN(fcn);
00146
00147 double arglist[10];
00148 int ierflg = 0;
00149
00150 arglist[0] = 1;
00151 minuit->mnexcm("SET ERR", arglist ,1,ierflg);
00152
00153
00154
00155
00156 minuit->mnparm(0, "Energy", vstrt[0], stp[0], 0,0,ierflg);
00157 minuit->mnparm(1, "Alpha", vstrt[1], stp[1], 0,0,ierflg);
00158 minuit->mnparm(2, "Starting point", vstrt[2], stp[2], 0,0,ierflg);
00159
00160
00161 arglist[0]=500;
00162 arglist[1]=1;
00163 minuit->mnexcm("MIGRAD",arglist,2,ierflg);
00164
00165
00166
00167 minuit->GetParameter( 0, fit_energy,energy_err );
00168 minuit->GetParameter( 1, fit_alpha,alpha_err );
00169 minuit->GetParameter( 2, fit_start,start_err );
00170 minuit->GetParameter( 3, fit_lambda,lambda_err );
00171
00172 arglist[0] = 3;
00173 minuit->mnexcm("CALL FCN", arglist ,1,ierflg);
00174
00175
00176 double edm,errdef;
00177 int nvpar,nparx,icstat;
00178 minuit->mnstat(ki2,edm,errdef,nvpar,nparx,icstat);
00179
00180
00181 data[i_CsI_FitEnergy] = fit_energy;
00182 data[i_Prof_Chisq] = ki2;
00183 data[i_CsI_Alpha] = fit_alpha;
00184 data[i_CsI_Lambda] = fit_lambda;
00185
00186
00187
00188 }
00189
00190
00191
00192
00193 CalProfile::CalProfile(CalRecon *c, TrackerRecon* t)
00194 :Recon(),cal(c),trk(t)
00195 {
00196 getParameters();
00197
00198 i_CsI_FitEnergy= data.addElement("CsI_Fit_Energy");
00199
00200 i_Prof_Chisq = data.addElement("Prof_Chisq");
00201
00202 i_CsI_Alpha = data.addElement("CsI_Alpha");
00203
00204 i_CsI_Lambda = data.addElement("CsI_Lambda");
00205
00206 i_CsI_Start = data.addElement("CsI_Start");
00207
00208 Init();
00209
00210 }
00211
00212 void CalProfile::getParameters ()
00213 {
00214
00215 num_layers = DetectorData::Calorimeter::numberOfLayers();
00216 s_rad_len = DetectorData::Calorimeter::radLen();
00217 mod_width = DetectorData::Tower::mod_width;
00218 s_wall_thickness = DetectorData::Tower::wall_thickness;
00219 s_wall_gap = DetectorData::Tower::wall_gap;
00220 s_xNum = DetectorData::Glast::xNum;
00221
00222
00223 s_inner_thickness = DetectorData::Calorimeter::gridInnerThickness();
00224 s_side_thickness = DetectorData::Calorimeter::sideThickness();
00225 s_total_thickness = s_inner_thickness + s_side_thickness;
00226 }
00227
00228
00229 void CalProfile::Init()
00230 {
00231
00232 minuit = new Midnight(5);
00233
00234
00235 minuit->SetFCN(fcn);
00236
00237 minuit->mninit(16,17,18);
00238
00239
00240
00241
00242
00243 eTotal = getCal()->data.getData("CsI_Energy_Sum");
00244
00245
00246 dirX = getTrk()->data.getData("Gamma_Xdir");
00247 dirY = getTrk()->data.getData("Gamma_Ydir");
00248 dirZ = getTrk()->data.getData("Gamma_Zdir");
00249
00250 centerX = getCal()->data.getData("CsI_X");
00251 centerY = getCal()->data.getData("CsI_Y");
00252 centerZ = getCal()->data.getData("CsI_Z");
00253
00254 }
00255
00256 void CalProfile::accept (ReconVisitor& rv)
00257 {
00258 rv.visit(this);
00259 }
00260
00261 void CalProfile::clear ()
00262 {
00263
00264 data.clear();
00265 eTotal = 0.0;
00266 nbins=0;
00267 layer;
00268 delta;
00269 slope=0;
00270 size=0;
00271 radlen=0;
00272 fit_energy=0;
00273 ki2=0;
00274 fit_alpha=0;
00275 fit_lambda=0;
00276 }