00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <stdlib.h>
00017 #include <stdio.h>
00018 #include <math.h>
00019
00020
00021 #include <hddm_s.h>
00022 #include <geant3.h>
00023 #include <bintree.h>
00024
00025 #include "calibDB.h"
00026 extern s_HDDM_t* thisInputEvent;
00027
00028
00029 static float ATTEN_LENGTH = 100.;
00030 static float C_EFFECTIVE = 15.;
00031 static float WIDTH_OF_BLOCK = 4.;
00032 static float LENGTH_OF_BLOCK = 45.;
00033 static float TWO_HIT_RESOL = 75.;
00034 static int MAX_HITS = 100;
00035 static float THRESH_MEV = 5.;
00036 static float ACTIVE_RADIUS = 120.;
00037 static int CENTRAL_ROW = 29;
00038 static int CENTRAL_COLUMN = 29;
00039
00040
00041 binTree_t* forwardEMcalTree = 0;
00042 static int blockCount = 0;
00043 static int showerCount = 0;
00044 static int initialized = 0;
00045
00046
00047
00048
00049 void hitForwardEMcal (float xin[4], float xout[4],
00050 float pin[5], float pout[5], float dEsum,
00051 int track, int stack, int history, int ipart)
00052 {
00053 float x[3], t;
00054 float xfcal[3];
00055 float zeroHat[] = {0,0,0};
00056
00057 if (!initialized){
00058
00059 mystr_t strings[50];
00060 float values[50];
00061 int nvalues = 50;
00062 int status = GetConstants("FCAL/fcal_parms", &nvalues, values, strings);
00063
00064 if (!status) {
00065
00066 int ncounter = 0;
00067 int i;
00068 for ( i=0;i<(int)nvalues;i++){
00069
00070 if (!strcmp(strings[i].str,"FCAL_ATTEN_LENGTH")) {
00071 ATTEN_LENGTH = values[i];
00072 ncounter++;
00073 }
00074
00075 if (!strcmp(strings[i].str,"FCAL_C_EFFECTIVE")) {
00076 C_EFFECTIVE = values[i];
00077 ncounter++;
00078 }
00079 if (!strcmp(strings[i].str,"FCAL_WIDTH_OF_BLOCK")) {
00080 WIDTH_OF_BLOCK = values[i];
00081 ncounter++;
00082 }
00083 if (!strcmp(strings[i].str,"FCAL_LENGTH_OF_BLOCK")) {
00084 LENGTH_OF_BLOCK = values[i];
00085 ncounter++;
00086 }
00087 if (!strcmp(strings[i].str,"FCAL_TWO_HIT_RESOL")) {
00088 TWO_HIT_RESOL = values[i];
00089 ncounter++;
00090 }
00091 if (!strcmp(strings[i].str,"FCAL_MAX_HITS")) {
00092 MAX_HITS = (int)values[i];
00093 ncounter++;
00094 }
00095 if (!strcmp(strings[i].str,"FCAL_THRESH_MEV")) {
00096 THRESH_MEV = values[i];
00097 ncounter++;
00098 }
00099 if (!strcmp(strings[i].str,"FCAL_ACTIVE_RADIUS")) {
00100 ACTIVE_RADIUS = values[i];
00101 ncounter++;
00102 }
00103 if (!strcmp(strings[i].str,"FCAL_CENTRAL_ROW")) {
00104 CENTRAL_ROW = (int)values[i];
00105 ncounter++;
00106 }
00107 if (!strcmp(strings[i].str,"FCAL_CENTRAL_COLUMN")) {
00108 CENTRAL_COLUMN = (int)values[i];
00109 ncounter++;
00110 }
00111 }
00112 const int nparams=10;
00113 if (ncounter==nparams){
00114 printf("FCAL: ALL parameters loaded from Data Base\n");
00115 } else if (ncounter<nparams){
00116 printf("FCAL: NOT ALL necessary parameters found in Data Base %d out of %d\n",ncounter,nparams);
00117 } else {
00118 printf("FCAL: SOME parameters found more than once in Data Base\n");
00119 }
00120 }
00121 initialized = 1;
00122 }
00123
00124 x[0] = (xin[0] + xout[0])/2;
00125 x[1] = (xin[1] + xout[1])/2;
00126 x[2] = (xin[2] + xout[2])/2;
00127 t = (xin[3] + xout[3])/2 * 1e9;
00128 transformCoord(x,"global",xfcal,"FCAL");
00129
00130
00131
00132 if ((history == 0) && (pin[3] > THRESH_MEV/1e3))
00133 {
00134 s_FcalTruthShowers_t* showers;
00135 int mark = (1<<30) + showerCount;
00136 void** twig = getTwig(&forwardEMcalTree, mark);
00137 if (*twig == 0)
00138 {
00139 s_ForwardEMcal_t* cal = *twig = make_s_ForwardEMcal();
00140 cal->fcalTruthShowers = showers = make_s_FcalTruthShowers(1);
00141 int a = thisInputEvent->physicsEvents->in[0].reactions->in[0].vertices->in[0].products->mult;
00142 showers->in[0].primary = (stack <= a);
00143 showers->in[0].track = track;
00144 showers->in[0].t = xin[3]*1e9;
00145 showers->in[0].x = xin[0];
00146 showers->in[0].y = xin[1];
00147 showers->in[0].z = xin[2];
00148 showers->in[0].px = pin[0]*pin[4];
00149 showers->in[0].py = pin[1]*pin[4];
00150 showers->in[0].pz = pin[2]*pin[4];
00151 showers->in[0].E = pin[3];
00152 showers->in[0].ptype = ipart;
00153 showers->mult = 1;
00154 showerCount++;
00155 }
00156 }
00157
00158
00159
00160 if (dEsum > 0)
00161 {
00162 int nhit;
00163 s_FcalTruthHits_t* hits;
00164 int row = getrow_wrapper_();
00165 int column = getcolumn_wrapper_();
00166
00167 float dist = 0.5*LENGTH_OF_BLOCK-xfcal[2];
00168 float dEcorr = dEsum * exp(-dist/ATTEN_LENGTH);
00169
00170
00171
00172 float tcorr = t + dist/C_EFFECTIVE;
00173 int mark = ((row+1)<<16) + (column+1);
00174 void** twig = getTwig(&forwardEMcalTree, mark);
00175 if (*twig == 0)
00176 {
00177 s_ForwardEMcal_t* cal = *twig = make_s_ForwardEMcal();
00178 s_FcalBlocks_t* blocks = make_s_FcalBlocks(1);
00179 blocks->mult = 1;
00180 blocks->in[0].row = row;
00181 blocks->in[0].column = column;
00182 blocks->in[0].fcalTruthHits = hits = make_s_FcalTruthHits(MAX_HITS);
00183 cal->fcalBlocks = blocks;
00184 blockCount++;
00185 }
00186 else
00187 {
00188 s_ForwardEMcal_t* cal = *twig;
00189 hits = cal->fcalBlocks->in[0].fcalTruthHits;
00190 }
00191
00192 for (nhit = 0; nhit < hits->mult; nhit++)
00193 {
00194 if (fabs(hits->in[nhit].t - tcorr) < TWO_HIT_RESOL)
00195 {
00196 break;
00197 }
00198 }
00199 if (nhit < hits->mult)
00200 {
00201 hits->in[nhit].t =
00202 (hits->in[nhit].t * hits->in[nhit].E + tcorr*dEcorr)
00203 / (hits->in[nhit].E += dEcorr);
00204 }
00205 else if (nhit < MAX_HITS)
00206 {
00207 hits->in[nhit].t = tcorr;
00208 hits->in[nhit].E = dEcorr;
00209 hits->mult++;
00210 }
00211 else
00212 {
00213 fprintf(stderr,"HDGeant error in hitforwardEMcal: ");
00214 fprintf(stderr,"max hit count %d exceeded, truncating!\n",MAX_HITS);
00215 exit(2);
00216 }
00217 }
00218 }
00219
00220
00221
00222 void hitforwardemcal_(float* xin, float* xout,
00223 float* pin, float* pout, float* dEsum,
00224 int* track, int* stack, int* history, int* ipart)
00225 {
00226 hitForwardEMcal(xin,xout,pin,pout,*dEsum,*track,*stack,*history, *ipart);
00227 }
00228
00229
00230
00231
00232 s_ForwardEMcal_t* pickForwardEMcal ()
00233 {
00234 s_ForwardEMcal_t* box;
00235 s_ForwardEMcal_t* item;
00236
00237 #if TESTING_CAL_CONTAINMENT
00238 double Etotal = 0;
00239 #endif
00240 if ((blockCount == 0) && (showerCount == 0))
00241 {
00242 return HDDM_NULL;
00243 }
00244
00245 box = make_s_ForwardEMcal();
00246 box->fcalBlocks = make_s_FcalBlocks(blockCount);
00247 box->fcalTruthShowers = make_s_FcalTruthShowers(showerCount);
00248 while (item = (s_ForwardEMcal_t*) pickTwig(&forwardEMcalTree))
00249 {
00250 s_FcalBlocks_t* blocks = item->fcalBlocks;
00251 int block;
00252 s_FcalTruthShowers_t* showers = item->fcalTruthShowers;
00253 int shower;
00254 for (block=0; block < blocks->mult; ++block)
00255 {
00256 int row = blocks->in[block].row;
00257 int column = blocks->in[block].column;
00258 float y0 = (row - CENTRAL_ROW)*WIDTH_OF_BLOCK;
00259 float x0 = (column - CENTRAL_COLUMN)*WIDTH_OF_BLOCK;
00260 float dist = sqrt(x0*x0+y0*y0);
00261
00262 s_FcalTruthHits_t* hits = blocks->in[block].fcalTruthHits;
00263
00264
00265 if (dist < ACTIVE_RADIUS)
00266 {
00267 int m = box->fcalBlocks->mult;
00268
00269
00270 int i,iok;
00271 for (iok=i=0; i < hits->mult; i++)
00272 {
00273 if (hits->in[i].E >= THRESH_MEV/1e3)
00274 {
00275 #if TESTING_CAL_CONTAINMENT
00276 Etotal += hits->in[i].E;
00277 #endif
00278 if (iok < i)
00279 {
00280 hits->in[iok] = hits->in[i];
00281 }
00282 ++iok;
00283 }
00284 }
00285 if (iok)
00286 {
00287 hits->mult = iok;
00288 box->fcalBlocks->in[m] = blocks->in[block];
00289 box->fcalBlocks->mult++;
00290 }
00291 else if (hits != HDDM_NULL)
00292 {
00293 FREE(hits);
00294 }
00295 }
00296 else if (hits != HDDM_NULL)
00297 {
00298 FREE(hits);
00299 }
00300 }
00301
00302 for (shower=0; shower < showers->mult; ++shower)
00303 {
00304 int m = box->fcalTruthShowers->mult++;
00305 box->fcalTruthShowers->in[m] = showers->in[shower];
00306 }
00307 if (blocks != HDDM_NULL)
00308 {
00309 FREE(blocks);
00310 }
00311 if (showers != HDDM_NULL)
00312 {
00313 FREE(showers);
00314 }
00315 FREE(item);
00316 }
00317
00318 blockCount = showerCount = 0;
00319
00320 if ((box->fcalBlocks != HDDM_NULL) &&
00321 (box->fcalBlocks->mult == 0))
00322 {
00323 FREE(box->fcalBlocks);
00324 box->fcalBlocks = HDDM_NULL;
00325 }
00326 if ((box->fcalTruthShowers != HDDM_NULL) &&
00327 (box->fcalTruthShowers->mult == 0))
00328 {
00329 FREE(box->fcalTruthShowers);
00330 box->fcalTruthShowers = HDDM_NULL;
00331 }
00332 if ((box->fcalBlocks->mult == 0) &&
00333 (box->fcalTruthShowers->mult == 0))
00334 {
00335 FREE(box);
00336 box = HDDM_NULL;
00337 }
00338 #if TESTING_CAL_CONTAINMENT
00339 printf("FCal energy sum: %f\n",Etotal/0.614);
00340 #endif
00341 return box;
00342 }