hitFCal.c

Go to the documentation of this file.
00001 /*
00002  * hitFCal - registers hits for forward calorimeter
00003  *
00004  * This is a part of the hits package for the
00005  * HDGeant simulation program for Hall D.
00006  *
00007  * version 1.0    -Richard Jones July 16, 2001
00008  *
00009  * changes: Wed Jun 20 13:19:56 EDT 2007 B. Zihlmann 
00010  *          add ipart to the function hitForwardEMcal
00011  *
00012  *       3/23/2012 B. Schaefer
00013  *          Removed radiation hard insert functionality
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.;   // cm/ns
00031 static float  WIDTH_OF_BLOCK  =   4.;   //cm
00032 static float  LENGTH_OF_BLOCK =  45.;   //cm
00033 static float  TWO_HIT_RESOL   =  75.;   // ns
00034 static int    MAX_HITS        =  100;   // maximum hits per block
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 /* register hits during tracking (from gustep) */
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     //printf("%d %s \n",i,strings[i].str);
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    /* post the hit to the truth tree */
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    /* post the hit to the hits tree, mark block as hit */
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)     /* merge with former hit */
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)         /* create new hit */
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 /* entry point from fortran */
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 /* pick and package the hits for shipping */
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          /* compress out the hits outside the active region */
00265          if (dist < ACTIVE_RADIUS)
00266          {
00267        int m = box->fcalBlocks->mult;
00268 
00269          /* compress out the hits below threshold */
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 }

Generated on 18 Jun 2013 for Hall-D Software by  doxygen 1.4.7