mEmcGeaClusterEval.c

Go to the documentation of this file.
00001 /*:>--------------------------------------------------------------------
00002 **: FILE:       mEmcGeaClusterEval.c.template
00003 **: HISTORY:
00004 **:             00jan93-v000a-hpl- Created by stic Version
00005 **:  Id: idl.y,v 1.3 1998/04/20 19:56:35 leitch Exp  
00006 **:<------------------------------------------------------------------*/
00007 #include "mEmcGeaClusterEval.h"
00008 #include "emlLib.h"
00009 
00025 long mEmcGeaClusterEval_(
00026   TABLE_HEAD_ST      *dEmcEvent_h,      DEMCEVENT_ST        *dEmcEvent ,
00027   TABLE_HEAD_ST   *dEmcGeaTrack_h,   DEMCGEATRACK_ST     *dEmcGeaTrack ,
00028   TABLE_HEAD_ST *dEmcGeaTowerTrack_h, DEMCGEATOWERTRACK_ST *dEmcGeaTowerTrack ,
00029   TABLE_HEAD_ST *dEmcClusterLocalExt_h, DEMCCLUSTERLOCALEXT_ST *dEmcClusterLocalExt ,
00030   TABLE_HEAD_ST *dEmcGeaTrackCluster_h, DEMCGEATRACKCLUSTER_ST *dEmcGeaTrackCluster ,
00031   TABLE_HEAD_ST *dEmcGeaClusterTrack_h, DEMCGEACLUSTERTRACK_ST *dEmcGeaClusterTrack )
00032 {
00033 /*:>--------------------------------------------------------------------
00034 **: ROUTINE:    mEmcGeaClusterEval_
00035 **: DESCRIPTION: Physics Analysis Module ANSI C template.
00036 **:             This is an ANSI C Physics Analysis Module template
00037 **:             automatically generated by stic from mEmcGeaClusterEval.idl.
00038 **:             Please edit comments and code.
00039 **: AUTHOR:     hpl - H.P. Lovecraft, hplovecraft@cthulhu.void
00040 **: ARGUMENTS:
00041 **:       IN:
00042 **:          dEmcEvent    - PLEASE FILL IN DESCRIPTION HERE
00043 **:         dEmcEvent_h   - header Structure for dEmcEvent
00044 **:       dEmcGeaTrack    - PLEASE FILL IN DESCRIPTION HERE
00045 **:      dEmcGeaTrack_h   - header Structure for dEmcGeaTrack
00046 **:  dEmcGeaTowerTrack    - PLEASE FILL IN DESCRIPTION HERE
00047 **:  dEmcGeaTowerTrack_h   - header Structure for dEmcGeaTowerTrack
00048 **:  dEmcClusterLocalExt    - PLEASE FILL IN DESCRIPTION HERE
00049 **:  dEmcClusterLocalExt_h   - header Structure for dEmcClusterLocalExt
00050 **:    INOUT:
00051 **:      OUT:
00052 **:  dEmcGeaTrackCluster    - PLEASE FILL IN DESCRIPTION HERE
00053 **:  dEmcGeaTrackCluster_h   - header Structure for dEmcGeaTrackCluster
00054 **:  dEmcGeaClusterTrack    - PLEASE FILL IN DESCRIPTION HERE
00055 **:  dEmcGeaClusterTrack_h   - header Structure for dEmcGeaClusterTrack
00056 **: RETURNS:    STAF Condition Value
00057 **:>------------------------------------------------------------------*/
00058 
00059 
00060 
00061   int i_cltr_id,i_trcl_id;
00062   int i,j,k,k1;
00063   int l_found,l_found1,l_found2;
00064   int i_track;
00065   int ll;   
00066   int i_twrkey;
00067   float ra_work[12];
00068   int   i_work1;
00069   float nom_edep;
00070 
00071   // Global boolean if one contributor is ever found in the cluster
00072   // needed for the real+simul merging !
00073   int AtLeastOneContributorFound = 0 ; 
00074 
00075   int maxNumOfTracksPerTower = 50;
00076 
00077   // We consider a realistic maximum of *3* tracks contributing to the same tower 
00078   // The most common case is, of course, 1 ...
00079   int maxNumOfTracksKeptPerTower = 3;  
00080 
00081   /* ia_track will store the track numbers of the tracks contributing
00082      to a specific cluster 
00083   */
00084   int   ia_track[maxNumOfTracksPerTower];
00085   
00086   /* ra_track will store data of tracks listed in ia_track.
00087      Field: 0 - energy (cumulates "edep" field of TowerTrack)
00088             1 - pid
00089             2 - ptot
00090             3-5 - impact xyz
00091             6 - twrhit
00092             7 - edep ("edep" field of GeaTrack)
00093             8 - anclvl
00094             9-11 - vertex xyz
00095   */
00096   float ra_track[12][maxNumOfTracksPerTower];
00097   
00098   if(dEmcGeaTrack_h->nok <=0) return (STAFCV_BAD);
00099   if(dEmcGeaTowerTrack_h->nok <=0) return (STAFCV_BAD);
00100   if(dEmcClusterLocalExt_h->nok <=0) return (STAFCV_BAD);
00101   
00102   i_cltr_id = 0;
00103 
00104   /* First part.  Figure out cluster overlaps, i.e. which track deposited */
00105   /* energy in a specific cluster */
00106 
00107   /* Loop over all clusters found */
00108 
00109   for( i = 0; i < dEmcClusterLocalExt_h->nok; i++)
00110     {
00111 
00112       // reset "AtLeastOneContributorFound" for each cluster
00113       AtLeastOneContributorFound = 0 ; 
00114 
00115       /* Zeroing temporary arrays */
00116 
00117       for (ll = 0; ll < sizeof(ra_track)/sizeof(ra_track[0][0]); ll++)
00118         {
00119           *((float *)ra_track + ll) = 0.0;
00120         }
00121       for (ll = 0; ll < sizeof(ia_track)/sizeof(ia_track[0]); ll++)
00122         {
00123           *(ia_track + ll) = 0;
00124         }
00125 
00126       /* Loop over all (16) towers included in a cluster */
00127 
00128       for( j = 0; j < 16 && dEmcClusterLocalExt[i].partesum[j] > 0.0; j++)
00129         {
00130           i_twrkey = dEmcClusterLocalExt[i].twrlist[j];
00131           
00132           /* Loop over all tracks contributing to a given tower */
00133 
00134           l_found = -1;
00135           k = 0;
00136           while( l_found < 0 && k < dEmcGeaTowerTrack_h->nok )
00137             {
00138               if( i_twrkey == dEmcGeaTowerTrack[k].twrkey)
00139                 {
00140                   l_found = k;
00141                   AtLeastOneContributorFound = 1 ; 
00142                 }
00143               k = k + 1;
00144             } /* while Loop over GeaTowerTrack to find contributor */
00145 
00146           if( l_found >= 0)  /* Contributor found */
00147             {
00148 
00149               /* We consider a maximum of *3* tracks contributing to the same tower */
00150 
00151               for( k = 0; k <= maxNumOfTracksKeptPerTower-1; k++)
00152                 {
00153                   i_track = dEmcGeaTowerTrack[l_found].trkno[k];
00154                   if( i_track > 0)
00155                     {
00156                       l_found1 = -1;
00157                       k1 = 0;
00158                       
00159                       while( l_found1 < 0 && k1 < maxNumOfTracksPerTower)
00160                         {
00161                           if( (ia_track[k1] == i_track) || (ia_track[k1] == 0))
00162                               l_found1 = k1;
00163                           k1 = k1 + 1;
00164 
00165                         }  /* while Loop over ia_track (already registered?) */
00166 
00167                       /* Let's hope you either found the track or there is
00168                          still free space in the array */
00169 
00170                       if( l_found1 >= 0)
00171                         {
00172                           ia_track[l_found1] = i_track;
00173                           ra_track[0][l_found1] = ra_track[0][l_found1] +
00174                             dEmcGeaTowerTrack[l_found].edep[k];
00175                         }
00176 
00177                     } /* trkno[k] > 0 */
00178 
00179                 } /* for Loop over k within a specific GeaTowerTrack record */
00180               
00181             }  /* l_found > 0, found tower */
00182           
00183           
00184         } /* for Loop over j, non-zero towers in a specific cluster */
00185 
00186       /*  You are done with all tower contributors of a cluster */
00187 
00188       if( AtLeastOneContributorFound )      
00189         {
00190           /* Sort them decreasing */
00191           for( j = 0; j < maxNumOfTracksPerTower - 1; j++)
00192             {
00193               /*          for( k = j + 1; k < maxNumOfTracksPerTower; k++) */
00194               for( k = 1; k < maxNumOfTracksPerTower; k++)
00195                 {
00196                   if(ra_track[0][k-1] < ra_track[0][k])
00197                     {
00198                       i_work1 = ia_track[k-1];
00199                       for ( k1 = 0; k1 <= 11; k1++) ra_work[k1] = ra_track[k1][k-1];
00200                       for ( k1 = 0; k1 <= 11; k1++) ra_track[k1][k-1] 
00201                                                       = ra_track[k1][k];
00202                       for ( k1 = 0; k1 <= 11; k1++) ra_track[k1][k] = ra_work[k1];
00203                       ia_track[k-1] = ia_track[k];
00204                       ia_track[k] = i_work1;
00205                     }  /* End interchange of elements */
00206                 }      /* End sort inner loop */
00207             }          /* End sort outer loop */
00208           
00209           /* Search pid and ptot for the top 3 tracks */
00210           
00211           for( j = 0; j <= maxNumOfTracksKeptPerTower-1; j++)
00212             {
00213               l_found2 = -1;
00214               k = 0;
00215               
00216               while( k < dEmcGeaTrack_h->nok && l_found2 < 0 && ia_track[j] > 0)
00217                 {
00218                   if(dEmcGeaTrack[k].trkno == ia_track[j])
00219                     {
00220                       l_found2 = k;
00221                     }
00222                   k = k + 1;
00223                   
00224                 } /* for Loop over k, entries in dEmcGeaTrack */
00225               
00226               if( l_found2 >= 0)
00227                 {
00228                   ra_track[1][j] = dEmcGeaTrack[l_found2].pid;
00229                   /*          ra_track[2][j] = dEmcGeaTrack[l_found2].ekin; */
00230                   ra_track[2][j] = dEmcGeaTrack[l_found2].ptot;
00231                   ra_track[3][j] = dEmcGeaTrack[l_found2].impxyz[0];
00232                   ra_track[4][j] = dEmcGeaTrack[l_found2].impxyz[1];
00233                   ra_track[5][j] = dEmcGeaTrack[l_found2].impxyz[2];
00234                   ra_track[6][j] = dEmcGeaTrack[l_found2].twrhit;
00235                   ra_track[7][j] = dEmcGeaTrack[l_found2].edep;
00236                   ra_track[8][j] = dEmcGeaTrack[l_found2].anclvl;
00237                   ra_track[9][j] = dEmcGeaTrack[l_found2].xyz[0];
00238                   ra_track[10][j] = dEmcGeaTrack[l_found2].xyz[1];
00239                   ra_track[11][j] = dEmcGeaTrack[l_found2].xyz[2];
00240                 }
00241               
00242             }    /* for Loop over j to search for pid at ptot of top 3 tracks */
00243 
00244         }  /* Contributor found */
00245 
00246       /* Write output record for this cluster */
00247 
00248       // In the case of embedded sim+real data, you often DO NOT find GEANT 
00249       // contributors to a reconstructed cluster. At this point we have, 
00250       // thus, 2 options:
00251       //
00252       // 1) Do not apply the AtLeastOneContributorFound condition:
00253       //    Fill dEmcGeaClusterTrack in all cases (though the *pure* dEmcGeaClusterTrack 
00254       //    fields below would be empty in most of the cases ...).
00255       //    In the analysis afterwards, the way to distinguish a "pure" ClusterTrack 
00256       //    (with some GEANT track in it) and a ClusterLocal without contribution
00257       //    will be, e.g., asking that the first track not be there (trkno_1 ==0).
00258       
00259       // 2) Apply the AtLeastOneContributorFound condition: Fill only dEmcGeaClusterTrack
00260       //    when a GEANT contributor is found. The resulting dEmcGeaClusterTrack
00261       //    tables are much less heavy, but we have to propagate the (real) event
00262       //    cluster multiplicity information in an adhoc manner ...
00263       //
00264       // We choose now option 2) and propagate the clus. mult. info in the 
00265       // unused "Charged" field of dEmcGeaClusterTrack D.d'E. (2002)
00266       // 
00267       
00268       if( AtLeastOneContributorFound )      
00269         {
00270           dEmcGeaClusterTrack[i_cltr_id].id = i_cltr_id;
00271           dEmcGeaClusterTrack[i_cltr_id].clusid = i;
00272           dEmcGeaClusterTrack[i_cltr_id].input = 0;
00273 
00274           // Fields common to dEmcClusterLocalExt
00275           dEmcGeaClusterTrack[i_cltr_id].evno = dEmcClusterLocalExt[i].evno;
00276           dEmcGeaClusterTrack[i_cltr_id].keycent = dEmcClusterLocalExt[i].twrlist[0];
00277           dEmcGeaClusterTrack[i_cltr_id].type = dEmcClusterLocalExt[i].type;
00278           dEmcGeaClusterTrack[i_cltr_id].arm  = dEmcClusterLocalExt[i].arm;
00279           dEmcGeaClusterTrack[i_cltr_id].sector = dEmcClusterLocalExt[i].sector;  
00280           dEmcGeaClusterTrack[i_cltr_id].mease = dEmcClusterLocalExt[i].e;
00281           
00282           // The ecore field of dEmcGeaClusterTrack stores now ecore for PbSc and ecorr for PbGl !
00283           if (dEmcGeaClusterTrack[i_cltr_id].type == 1 ) // PbSc
00284             dEmcGeaClusterTrack[i_cltr_id].ecore = dEmcClusterLocalExt[i].ecore;
00285           if (dEmcGeaClusterTrack[i_cltr_id].type == 2)  // PbGl
00286             dEmcGeaClusterTrack[i_cltr_id].ecore = dEmcClusterLocalExt[i].ecorr;
00287           
00288           dEmcGeaClusterTrack[i_cltr_id].tof = dEmcClusterLocalExt[i].tof;
00289           dEmcGeaClusterTrack[i_cltr_id].tofmin = dEmcClusterLocalExt[i].tofmin;
00290           dEmcGeaClusterTrack[i_cltr_id].tofmax = dEmcClusterLocalExt[i].tofmax;
00291           // the energy of the first-TOF tower is the energy of the highest tower:
00292           dEmcGeaClusterTrack[i_cltr_id].etof = dEmcClusterLocalExt[i].ecent;
00293           dEmcGeaClusterTrack[i_cltr_id].etofmin = dEmcClusterLocalExt[i].etofmin;
00294           dEmcGeaClusterTrack[i_cltr_id].etofmax = dEmcClusterLocalExt[i].etofmax;
00295           dEmcGeaClusterTrack[i_cltr_id].twrhit = dEmcClusterLocalExt[i].twrhit;
00296           
00297           for ( k=0 ; k<= 2 ; k++)
00298             {
00299               dEmcGeaClusterTrack[i_cltr_id].e_sh[k] = dEmcClusterLocalExt[i].e_sh[k];
00300               dEmcGeaClusterTrack[i_cltr_id].disp[k] = dEmcClusterLocalExt[i].disp[k];
00301               dEmcGeaClusterTrack[i_cltr_id].padisp[k] = dEmcClusterLocalExt[i].padisp[k];
00302               dEmcGeaClusterTrack[i_cltr_id].measxyz[k] = dEmcClusterLocalExt[i].xyz[k];
00303             } 
00304           for( k=0; k<=8; k++)
00305             {
00306               dEmcGeaClusterTrack[i_cltr_id].partesum[k] = dEmcClusterLocalExt[i].partesum[k];
00307             }
00308           
00309           // Fields common to dEmcClusterLocalExt but somehow different ...
00310           dEmcGeaClusterTrack[i_cltr_id].chi2_sh = dEmcClusterLocalExt[i].chi2 ;
00311           dEmcGeaClusterTrack[i_cltr_id].prob_photon_sh = dEmcClusterLocalExt[i].prob_photon ;
00312           
00313           // "Pure" dEmcGeaClusterTrack fields
00314           
00315           for( k = 0 ; k<= maxNumOfTracksKeptPerTower-1 ; k++)
00316             {
00317               dEmcGeaClusterTrack[i_cltr_id].trkno[k] = ia_track[k];
00318               dEmcGeaClusterTrack[i_cltr_id].edep[k] = ra_track[0][k];
00319               dEmcGeaClusterTrack[i_cltr_id].pid[k] = ra_track[1][k];
00320               dEmcGeaClusterTrack[i_cltr_id].ptot[k] = ra_track[2][k];
00321               dEmcGeaClusterTrack[i_cltr_id].tracktwrhit[k] = ra_track[6][k];
00322               dEmcGeaClusterTrack[i_cltr_id].edep_nom[k] = ra_track[7][k];
00323               dEmcGeaClusterTrack[i_cltr_id].ancestry[k] = ra_track[8][k];
00324               for( j = 0; j <= 2; j++)
00325                 {
00326                   dEmcGeaClusterTrack[i_cltr_id].xyz[j][k] = ra_track[3+j][k];
00327                   dEmcGeaClusterTrack[i_cltr_id].vertex[j][k] = ra_track[9+j][k];
00328                 }
00329             }
00330           
00331           if(dEmcGeaClusterTrack[i_cltr_id].mease > 0.0)
00332             {
00333               for( k =0; k <= maxNumOfTracksKeptPerTower-1 ; k++)
00334                 {
00335                   dEmcGeaClusterTrack[i_cltr_id].efrac[k] =
00336                     dEmcGeaClusterTrack[i_cltr_id].edep[k] /
00337                     dEmcGeaClusterTrack[i_cltr_id].mease;
00338                 }
00339             }
00340           
00341           // "Pure" dEmcGeaClusterTrack fields not used
00342 
00343           // WATCH-OUT: we (ab)use of this field to store the real evt. cluster info
00344           // dEmcGeaClusterTrack[i_cltr_id].charged = 0;
00345           dEmcGeaClusterTrack[i_cltr_id].charged = (long)dEmcClusterLocalExt_h->nok;
00346 
00347           for( k=0; k<8; k++)
00348             {
00349               dEmcGeaClusterTrack[i_cltr_id].chglist[k] = 0.;
00350             }
00351 
00352           // WATCH-OUT: we (ab)use of this field to store the dead/warn map info
00353           //for( k=0; k<3; k++)
00354           //  {
00355           //   dEmcGeaClusterTrack[i_cltr_id].pc3proj[k] = 0.;
00356           //  }
00357 
00358           dEmcGeaClusterTrack[i_cltr_id].pc3proj[0] = (float)dEmcClusterLocalExt[i].deadmap; // (21+9 bits int stored in float)
00359           dEmcGeaClusterTrack[i_cltr_id].pc3proj[1] = (float)dEmcClusterLocalExt[i].warnmap; // (21+9 bits int stored in float)
00360 
00361 
00362           dEmcGeaClusterTrack[i_cltr_id].pc3proj[2] = 0;
00363 
00364           /* Increment STAF row counter */
00365           i_cltr_id = i_cltr_id + 1;
00366       
00367         } /* End of  if( AtLeastOneContributorFound ) , i.e. you found at least one GEANT
00368              contributor to this cluster */
00369       
00370     }    /* Loop over i, all clusters recognized in dEmcClusterLocalExt */
00371   
00372   dEmcGeaClusterTrack_h->nok = i_cltr_id;
00373   
00374 
00375   /* -------------------------------------------------------------   */
00376 
00377   /* Second part.  Loop over all tracks that deposited anything in the 
00378      calorimeter.  Point to clusters where a specific track contributed */
00379 
00380   i_trcl_id = 0;
00381 
00382   for ( i = 0; i < dEmcGeaTrack_h->nok; i++)
00383     {
00384 
00385       l_found = -1;   /* Found at least one cluster where it contributed */
00386       AtLeastOneContributorFound = 0 ; 
00387 
00388       // Zeroing arrays
00389       for (ll = 0; ll < sizeof(ra_track)/sizeof(ra_track[0][0]); ll++)
00390         {
00391           *((float *)ra_track + ll) = 0;
00392         }
00393 
00394       /* Since 0 is a valid pointer now, "not found" is indicated
00395          by -1 */
00396       for(j = 0; j <= maxNumOfTracksKeptPerTower-1 ; j++) ia_track[j] = -1;
00397       i_track = dEmcGeaTrack[i].trkno;
00398       nom_edep = dEmcGeaTrack[i].edep;
00399       
00400       for ( j = 0; j < dEmcGeaClusterTrack_h->nok; j++)
00401         {
00402           for ( k = 0; k <= maxNumOfTracksKeptPerTower-1 ; k++)
00403             {
00404               if ( dEmcGeaClusterTrack[j].trkno[k] == i_track
00405                    && l_found < maxNumOfTracksPerTower - 1 )
00406                 {
00407                   l_found = l_found + 1; 
00408                   AtLeastOneContributorFound = 1 ; 
00409                   ia_track[l_found] = dEmcGeaClusterTrack[j].clusid;
00410                   ra_track[0][l_found] = dEmcGeaClusterTrack[j].pid[k];
00411                   ra_track[1][l_found] = dEmcGeaClusterTrack[j].ptot[k];
00412                   ra_track[2][l_found] = dEmcGeaClusterTrack[j].edep[k];
00413                   /*
00414                   ra_track[3][l_found] = dEmcGeaClusterTrack[j].efrac[k];
00415                   */
00416                   if(nom_edep > 0.1)
00417                     {
00418                       
00419                       ra_track[3][l_found] = 
00420                         dEmcGeaClusterTrack[j].edep[k] / nom_edep;
00421                     }
00422                   else
00423                     {
00424                       ra_track[3][l_found] = 0.0;
00425                     }
00426                 }  /* New cluster found where it contributed */
00427               
00428             }  /* Loop over k = 0, 2, within one dEmcGeaClusterTrack record */
00429           
00430         }   /* Loop over j = 0,dEmcGeaClusterTrack_h.nok   */
00431 
00432       /* Sort descending the clusters where the track contributed */
00433 
00434       if ( AtLeastOneContributorFound )
00435         {
00436           for (j = 0; j < l_found; j++)
00437             {
00438               for ( k = 1; k <= l_found; k++) 
00439                 {
00440                   if (ra_track[3][k-1] < ra_track[3][k])
00441                     {
00442                       i_work1 = ia_track[k-1];
00443                       for ( k1 = 0; k1 <= 11; k1++) ra_work[k1] = 
00444                                                      ra_track[k1][k-1];
00445                       for ( k1 = 0; k1 <= 11; k1++) ra_track[k1][k-1] 
00446                                                      = ra_track[k1][k];
00447                       for ( k1 = 0; k1 <= 11; k1++) ra_track[k1][k] = 
00448                                                      ra_work[k1];
00449                       ia_track[k-1] = ia_track[k];
00450                       ia_track[k] = i_work1;
00451                     }
00452                 }  /* End loop over k, inner sort loop */
00453             }      /* End loop over j, outer sort loop */
00454       
00455           /* Write out a new record of dEmcGeaTrackCluster */
00456           
00457           dEmcGeaTrackCluster[i_trcl_id].id = i_trcl_id + 1;
00458           dEmcGeaTrackCluster[i_trcl_id].trkno = i_track;
00459           dEmcGeaTrackCluster[i_trcl_id].track_ptr = i;
00460           dEmcGeaTrackCluster[i_trcl_id].nom_edep = nom_edep;
00461           dEmcGeaTrackCluster[i_trcl_id].input = 0;
00462           for (k = 0; k <= maxNumOfTracksKeptPerTower-1 ; k++)
00463             {
00464               dEmcGeaTrackCluster[i_trcl_id].clusid[k] = ia_track[k];
00465               dEmcGeaTrackCluster[i_trcl_id].pid = ra_track[0][0];
00466               dEmcGeaTrackCluster[i_trcl_id].ptot = ra_track[1][0];
00467               dEmcGeaTrackCluster[i_trcl_id].edep[k] = ra_track[2][k];
00468               dEmcGeaTrackCluster[i_trcl_id].efrac[k] = ra_track[3][k];
00469             }
00470 
00471           i_trcl_id = i_trcl_id + 1;
00472           
00473 
00474         }   /* End if(l_found) - found at least one cluster where contrib. */
00475       
00476 
00477       
00478     }   /*  Loop over i = 0,dEmcGeaTrack_h.nok , all tracks depositing E */
00479   
00480 
00481   dEmcGeaTrackCluster_h->nok = i_trcl_id;
00482   
00483 
00484     return STAFCV_OK;
00485 }