mEmcClusterNewModule.C

Go to the documentation of this file.
00001 // EMC basic clustering class (for PHOOL).
00002 // Alexander Bazilevsky Sep-00
00003 
00004 #include "mEmcClusterNewModule.h"
00005 #include "PHCompositeNode.h"
00006 #include "mEmcGeometryModule.h"
00007 #include "EmcCluster.h"
00008 
00009 #include "VtxOut.h"
00010 #include "dEmcCalibTowerWrapper.h"
00011 #include "dEmcClusterLocalExtWrapper.h"
00012 
00013 #include "PHNode.h"
00014 #include "PHCompositeNode.h"
00015 #include "PHIODataNode.h"
00016 #include "PHNodeIterator.h"
00017 #include "PHTable.hh"
00018 
00019 #include <cstdio>
00020 #include <cmath>
00021 #include <cstdlib>
00022 #include <iostream>
00023 
00024 using namespace std;
00025 
00026 typedef PHIODataNode<PHTable> TableNode_t;
00027 
00028 #define MAX_SECTORS_PROCESS 8
00029 #define MaxNofPeaks 10
00030 #define HITS_TO_TABLE   16
00031 
00032 mEmcClusterNewModule::mEmcClusterNewModule(mEmcGeometryModule* geom,
00033                                            int runnumber)
00034 {
00035   name = "mEmcClusterNewModule";
00036 
00037   int is;
00038   int arm, sector;
00039   int nx, ny;
00040   float txsz, tysz;
00041   PHMatrix emcrm;
00042   PHVector emctr;
00043   float TowerThresh = 0.003;
00044   float PeakThresh = 0.08;
00045   float eClMin = 0.02;
00046   EmcSectorRec *SectorRec;
00047   SecGeom SecGeometry;
00048 
00049   fRunNumber = runnumber;
00050 
00051   for (is = 0; is < MAX_SECTORS_PROCESS; is++)
00052     {
00053       SectorRec = (is < 6) ? (EmcSectorRec *)&ScSector[is] : (EmcSectorRec *)&GlSector[is - 6];
00054 
00055       // Parmeters for Shower reconstruction
00056       SectorRec->SetTowerThreshold(TowerThresh);
00057       SectorRec->SetPeakThreshold(PeakThresh);
00058       SectorRec->SetChi2Limit(2);
00059 
00060       if (is <= 3)
00061         {
00062           arm = 0;
00063           sector = is;
00064         }
00065       else
00066         {
00067           arm = 1;
00068           sector = 7 - is;
00069         }
00070 
00071       geom->GetSectorDim(is, nx, ny);
00072       geom->GetTowerSize(is, txsz, tysz);
00073       geom->GetMatrixVector(is, emcrm, emctr);
00074 
00075       SecGeometry.nx = nx;
00076       SecGeometry.ny = ny;
00077       SecGeometry.Tower_xSize = txsz;
00078       SecGeometry.Tower_ySize = tysz;
00079 
00080       SectorRec->SetGeometry(SecGeometry, &emcrm, &emctr);
00081     }
00082 
00083   SetMinClusterEnergy(eClMin);
00084 }
00085 
00086 void 
00087 mEmcClusterNewModule::SetTowerThreshold(float Thresh)
00088 {
00089   for (int is = 0; is < MAX_SECTORS_PROCESS; is++)
00090     {
00091       if (is < 6)
00092         {
00093           ScSector[is].SetTowerThreshold(Thresh);
00094         }
00095       else
00096         {
00097           GlSector[is - 6].SetTowerThreshold(Thresh);
00098         }
00099     }
00100 }
00101 
00102 void
00103 mEmcClusterNewModule::SetTowerThreshold(int is, float Thresh)
00104 {
00105   if (is < 0 || is >= MAX_SECTORS_PROCESS)
00106     {
00107       cout << PHWHERE << "Wrong sector index:" << is << endl;
00108       return;
00109     }
00110   if (is < 6)
00111     {
00112       ScSector[is].SetTowerThreshold(Thresh);
00113     }
00114   else
00115     {
00116       GlSector[is - 6].SetTowerThreshold(Thresh);
00117     }
00118 }
00119 
00120 void
00121 mEmcClusterNewModule::SetTowerThresholdPbSc(float Thresh)
00122 {
00123   for (int is = 0; is < 6; is++)
00124     {
00125       ScSector[is].SetTowerThreshold(Thresh);
00126     }
00127 }
00128 
00129 void mEmcClusterNewModule::SetTowerThresholdPbGl(float Thresh)
00130 {
00131   for (int is = 0; is < 2; is++)
00132     {
00133       GlSector[is].SetTowerThreshold(Thresh);
00134     }
00135 }
00136 
00137 void 
00138 mEmcClusterNewModule::SetPeakThreshold(float Thresh)
00139 {
00140   for (int is = 0; is < MAX_SECTORS_PROCESS; is++)
00141     {
00142       if (is < 6)
00143         {
00144           ScSector[is].SetPeakThreshold(Thresh);
00145         }
00146       else
00147         {
00148           GlSector[is - 6].SetPeakThreshold(Thresh);
00149         }
00150     }
00151 }
00152 
00153 void
00154 mEmcClusterNewModule::SetPeakThreshold(int is, float Thresh)
00155 {
00156   if (is < 0 || is >= MAX_SECTORS_PROCESS)
00157     {
00158       cout << PHWHERE << "Wrong sector index:" << is << endl;
00159       return;
00160     }
00161   if (is < 6)
00162     {
00163       ScSector[is].SetPeakThreshold(Thresh);
00164     }
00165   else
00166     {
00167       GlSector[is - 6].SetPeakThreshold(Thresh);
00168     }
00169 }
00170 
00171 PHBoolean
00172 mEmcClusterNewModule::event(PHCompositeNode *root)
00173 {
00174   PHNodeIterator it(root);
00175   float lactual, lnominal;
00176   float Vertex[3] = {0, 0, 0};
00177   vector<EmcModule> HitList[MAX_SECTORS_PROCESS];
00178   EmcModule vhit;
00179   EmcModule HVect[HITS_TO_TABLE];
00180   vector<EmcCluster> *ClusterList;
00181   vector<EmcCluster>::iterator pc;
00182   EmcPeakarea pPList[MaxNofPeaks];
00183   EmcPeakarea *pp;
00184   EmcModule peaks[MaxNofPeaks];
00185   int i, iy, iz, is, ip, ih, ich, ind;
00186   float TowerThresh[MAX_SECTORS_PROCESS];
00187   int Nx[MAX_SECTORS_PROCESS];
00188   float MinClusterEnergy;
00189   EmcSectorRec *SectorRec;
00190   int nCluster, nPeakArea, nShower;
00191   int nCl, nh, npk;
00192   int arm, sector;
00193   EmcModule hmax, himp;
00194   float de, rmax, rimp, e, e9, re9, chi2, pr;
00195   float ecore, ecorr, ecorecorr, xcg, ycg, xcgm, ycgm;
00196   float xx, xy, yy, xc, yc, xgl, ygl, zgl, tof, tofcorr, etof;
00197   float dtof, tofmin, tofmincorr, etofmin, tofmax, tofmaxcorr;
00198   float etofmax, dd, dx, dy, dz, e_max_cl;
00199   int dead, ndead, warnmap;
00200   float qual;
00201   int evno = -9999;
00202 
00203   float padisp[2], pahelp;
00204 
00205 
00206   // dEmcCalibTower
00207   PHIODataNode<PHTable>* dEmcCalibTowerNode =
00208     (PHIODataNode<PHTable>*)it.findFirst("PHIODataNode", "dEmcCalibTower");
00209   dEmcCalibTowerWrapper * dEmcCalibTower =
00210     static_cast<dEmcCalibTowerWrapper*>(dEmcCalibTowerNode->getData());
00211   TABLE_HEAD_ST dEmcCalibTower_h = dEmcCalibTower->TableHeader();
00212 
00213   PHIODataNode<PHTable>* dEmcClusterLocalExtNode =
00214     (PHIODataNode<PHTable>*)it.findFirst("PHIODataNode", "dEmcClusterLocalExt");
00215   dEmcClusterLocalExtWrapper * dEmcClusterLocalExt =
00216     static_cast<dEmcClusterLocalExtWrapper*>(dEmcClusterLocalExtNode->getData());
00217   dEmcClusterLocalExt->SetRowCount(0);
00218 
00219   PHIODataNode<PHObject>* vtxoutnode =
00220     (PHIODataNode<PHObject>*)it.findFirst("PHIODataNode", "VtxOut");
00221 
00222   VtxOut* vtxout = NULL;
00223   if (vtxoutnode)
00224     {
00225       vtxout = static_cast<VtxOut*>(vtxoutnode->getData());
00226     }
00227 
00228   if (!vtxoutnode || !vtxout)
00229     {
00230       cout << PHWHERE << " No information (vtxout) about vertex. Assuming "
00231            << "(0,0,0)" << endl;
00232 
00233       for (i = 0; i < 3; i++)
00234         {
00235           Vertex[i] = 0.0;
00236         }
00237     }
00238   else
00239     {
00240       PHPoint vertex = vtxout->get_Vertex();
00241       Vertex[0] = vertex.getX();
00242       Vertex[1] = vertex.getY();
00243       Vertex[2] = vertex.getZ();
00244     }
00245   
00246   if (fRunNumber == 0)
00247     {
00248       fRunNumber = 27000;
00249     }
00250 
00251   if (!(fabs(Vertex[0]) < 10.0 &&
00252         fabs(Vertex[1]) < 10.0 &&
00253         fabs(Vertex[2]) < 100.0))
00254     {
00255       cout << PHWHERE << "No clustering done, bad Vertex=("
00256            << Vertex[0] << ", "
00257            << Vertex[1] << ", "
00258            << Vertex[2] << ")"
00259            << endl;
00260       return false;
00261     }
00262 
00263   //=========> Filling Hit List <==========
00264   for (is = 0; is < MAX_SECTORS_PROCESS; is++)
00265     {
00266       if (is < 6)
00267         {
00268           SectorRec = &(ScSector[is]);
00269         }
00270       else
00271         {
00272           SectorRec = &(GlSector[is - 6]);
00273         }
00274       TowerThresh[is] = SectorRec->GetTowerThreshold();
00275       Nx[is] = SectorRec->GetNx();
00276     }
00277   for (is = 0; is < MAX_SECTORS_PROCESS; is++)
00278     {
00279       // Clean up hits list
00280       HitList[is].erase(HitList[is].begin(), HitList[is].end());
00281     }
00282   if (dEmcCalibTower_h.nok <= 0)
00283     {
00284       return true;
00285     }
00286   for (i = 0; i < dEmcCalibTower_h.nok; i++)
00287     {
00288       // Start looping on fired modules
00289       iz = dEmcCalibTower->get_ind(0, i);
00290       iy = dEmcCalibTower->get_ind(1, i);
00291       is = dEmcCalibTower->get_sector(i);
00292 
00293       // If it's in the East Arm
00294       if (dEmcCalibTower->get_arm(i) == 1)
00295         {
00296           is = 7 - is;
00297         }
00298       if (is < 0 || is > MAX_SECTORS_PROCESS)
00299         {
00300           printf(" ?????? EmcClusterLocalChi2: Sector number = %d\n", is);
00301           return false;
00302         }
00303 
00304       de = dEmcCalibTower->get_ecal(i);
00305       tof = dEmcCalibTower->get_tof(i);
00306       dead = dEmcCalibTower->get_deadmap(i);
00307       warnmap = dEmcCalibTower->get_warnmap(i); // MV 2001/12/06
00308 
00309       vhit.ich = iy * Nx[is] + iz;
00310       vhit.amp = de;
00311       vhit.tof = tof;
00312       vhit.deadmap = dead;
00313       vhit.warnmap = warnmap; // MV 2001/12/06
00314 
00315       // MV 2001/09/25
00316       vhit.adc = dEmcCalibTower->get_adc(i);
00317       vhit.tac = dEmcCalibTower->get_tac(i);
00318 
00319       if (de > TowerThresh[is])
00320         {
00321           HitList[is].push_back(vhit);
00322         }
00323     } // Finished looping on fired modules
00324 
00325   nCluster = 0;
00326   nPeakArea = 0;
00327   nShower = 0;
00328 
00329   //==========> Start looping over sectors <==========
00330   for (is = 0; is < MAX_SECTORS_PROCESS; is++)
00331     {
00332       SectorRec = (is < 6) ? (EmcSectorRec *)&ScSector[is] : (EmcSectorRec *)&GlSector[is - 6];
00333       if (is <= 3)
00334         {
00335           arm = 0;
00336           sector = is;
00337         }
00338       else
00339         {
00340           arm = 1;
00341           sector = 7 - is;
00342         }
00343 
00344       MinClusterEnergy = (is < 6) ? fMinClusterEnergySc : fMinClusterEnergyGl;
00345 
00346       SectorRec->SetVertex(Vertex);
00347       SectorRec->SetModules(&HitList[is]);
00348       nCl = SectorRec->FindClusters();
00349       ClusterList = SectorRec->GetClusters();
00350 
00351       if (nCl < 0)
00352         {
00353           printf(" ?????? EmcClusterChi2: Increase parameter MaxLen !!!\n");
00354           return false;
00355         }
00356       // Fill cluster table 
00357       // Start looping on clusters
00358       for (pc = ClusterList->begin(); pc != ClusterList->end(); pc++)
00359         {
00360           npk = pc->GetPeaks(pPList, peaks);
00361           pp = pPList;
00362 
00363           // Fill PeakArea table 
00364           for (ip = 0; ip < npk; ip++)
00365             { 
00366               // Start looping over peak areas
00367               if (pp->GetTotalEnergy() > MinClusterEnergy)
00368                 {
00369                   nh = pp->GetNofHits();
00370                   hmax = pp->GetMaxTower();
00371                   ndead = pp->GetNDead();
00372                   qual = ndead ? 1.0 : -ndead;
00373                   rmax = (hmax.amp > 0) ? 
00374                     hmax.amp / pc->GetTowerEnergy(hmax.ich) : 0;
00375                   himp = pp->GetImpactTower();
00376                   rimp = (himp.amp > 0) ? 
00377                     himp.amp / pc->GetTowerEnergy(himp.ich) : 0;
00378                   pp->GetChar(&e, &ecorr, &ecore, &ecorecorr,
00379                               &xcg, &ycg, &xcgm, &ycgm,
00380                               &xc, &yc, &xgl, &ygl, &zgl,
00381                               &xx, &xy, &yy, &chi2, &de, &dx, &dy, &dz);
00382                   e9 = pp->GetE9(hmax.ich);
00383                   re9 = (e9 > 0) ? e9 / pc->GetE9(hmax.ich) : 0.0;
00384                   pp->GetHits(HVect, HITS_TO_TABLE);
00385                   e_max_cl = pc->GetTowerEnergy(hmax.ich);
00386 
00387                   // Principal axis dispersion (eigenvalues)  Nov 17, 2001, GD
00388                   padisp[0] = 2.0;
00389                   padisp[1] = 1.0;
00390                   pahelp = (xx + yy) * (xx + yy) - 4.0 * (xx * yy - xy * xy);
00391                   pahelp = sqrt(abs(pahelp));
00392                   padisp[0] = (xx + yy + pahelp) / 2.0;
00393                   padisp[1] = (xx + yy - pahelp) / 2.0;
00394                   if (is < 6)
00395                     {
00396                       if (fRunNumber < 20000)
00397                         {
00398                           dd = sqrt((Vertex[0] - xgl) * (Vertex[0] - xgl) +
00399                                     (Vertex[1] - ygl) * (Vertex[1] - ygl) +
00400                                     (Vertex[2] - zgl) * (Vertex[2] - zgl));
00401                         }
00402                       else
00403                         {
00404                           //  PbSc now also uses physics-extracted nominal T0
00405                           //  w.r.t. vertex (0,0,0).  However, this is only
00406                           //  valid for Year-2 data analysis
00407                           lactual = sqrt(pow(Vertex[0] - xgl, 2) +
00408                                          pow(Vertex[1] - ygl, 2) +
00409                                          pow(Vertex[2] - zgl, 2));
00410                           lnominal = sqrt(xgl * xgl + ygl * ygl + zgl * zgl);
00411                           dd = lactual - lnominal;
00412                         }
00413                     }
00414                   else
00415                     {
00416                       // This is needed because simulated times for the
00417                       // PbGl do not have their flashtime subtracted
00418                       if (fRunNumber < 1000)
00419                         {
00420                           dd = sqrt((Vertex[0] - xgl) * (Vertex[0] - xgl) +
00421                                     (Vertex[1] - ygl) * (Vertex[1] - ygl) +
00422                                     (Vertex[2] - zgl) * (Vertex[2] - zgl));
00423                         }
00424                       else
00425                         {
00426                           // MV 2001/09/18 for PbGl nominal T0 is taken
00427                           // into account during calibration.  We need
00428                           // just correct for vertex deviation from
00429                           // (0,0,0)
00430                           lactual = sqrt(pow(Vertex[0] - xgl, 2) +
00431                                          pow(Vertex[1] - ygl, 2) +
00432                                          // pow(Vertex[1] - ygl, 2));
00433                                          pow(Vertex[2] - zgl, 2));
00434                           lnominal = sqrt(xgl * xgl + ygl * ygl + zgl * zgl);
00435                           dd = lactual - lnominal;
00436                         }
00437                     }
00438               
00439                   ToF_Process(HVect, dd, hmax,
00440                               &tof, &etof, &tofcorr, &dtof,
00441                               &tofmin, &etofmin, &tofmincorr,
00442                               &tofmax, &etofmax, &tofmaxcorr);
00443 
00444                 
00445                   pr = pp->GetCL();
00446                  
00447                   dEmcClusterLocalExt->set_id(nPeakArea, nPeakArea);
00448                   dEmcClusterLocalExt->set_runno(nPeakArea, fRunNumber);
00449                   dEmcClusterLocalExt->set_evno(nPeakArea, evno);
00450                   dEmcClusterLocalExt->set_arm(nPeakArea, arm);
00451                   dEmcClusterLocalExt->set_sector(nPeakArea, sector);
00452                   if (is < 6)
00453                     {
00454                       dEmcClusterLocalExt->set_type(nPeakArea, 1);
00455                     }
00456                   else
00457                     {
00458                       dEmcClusterLocalExt->set_type(nPeakArea, 2);
00459                     }
00460                   dEmcClusterLocalExt->set_method(nPeakArea, 2);
00461                   dEmcClusterLocalExt->set_xyz(0, nPeakArea, xgl);
00462                   dEmcClusterLocalExt->set_xyz(1, nPeakArea, ygl);
00463                   dEmcClusterLocalExt->set_xyz(2, nPeakArea, zgl);
00464                   dEmcClusterLocalExt->set_dxyz(0, nPeakArea, dx);
00465                   dEmcClusterLocalExt->set_dxyz(1, nPeakArea, dy);
00466                   dEmcClusterLocalExt->set_dxyz(2, nPeakArea, dz);
00467                   dEmcClusterLocalExt->set_e(nPeakArea, e);
00468                   dEmcClusterLocalExt->set_ecore(nPeakArea, ecorecorr);
00469                   dEmcClusterLocalExt->set_ecorr(nPeakArea, ecorr);
00470                   dEmcClusterLocalExt->set_de(nPeakArea, de);
00471                   dEmcClusterLocalExt->set_ecent(nPeakArea, e_max_cl);
00472                   dEmcClusterLocalExt->set_chi2(nPeakArea, chi2);
00473                   dEmcClusterLocalExt->set_tof(nPeakArea, tof);
00474                   dEmcClusterLocalExt->set_tofcorr(nPeakArea, tofcorr);
00475                   dEmcClusterLocalExt->set_dtof(nPeakArea, dtof);
00476                   dEmcClusterLocalExt->set_qual(nPeakArea, qual);
00477                   dEmcClusterLocalExt->set_pid(nPeakArea, 0);
00478                   dEmcClusterLocalExt->set_prob_photon(nPeakArea, pr);
00479                   dEmcClusterLocalExt->set_prob_neuhad(nPeakArea, 0);
00480                   dEmcClusterLocalExt->set_theta(nPeakArea, 0);
00481                   dEmcClusterLocalExt->set_phi(nPeakArea, 0);
00482                   dEmcClusterLocalExt->set_unitv(0, nPeakArea, 0);
00483                   dEmcClusterLocalExt->set_unitv(1, nPeakArea, 0);
00484                   dEmcClusterLocalExt->set_unitv(2, nPeakArea, 0);
00485                   iy = hmax.ich / Nx[is];
00486                   iz = hmax.ich - iy * Nx[is];
00487                   dEmcClusterLocalExt->set_ind(0, nPeakArea, iz);
00488                   dEmcClusterLocalExt->set_ind(1, nPeakArea, iy);
00489                   dEmcClusterLocalExt->set_twrhit(nPeakArea, nh);
00490                   dEmcClusterLocalExt->set_tofmin(nPeakArea, tofmin);
00491                   dEmcClusterLocalExt->set_etofmin(nPeakArea, etofmin);
00492                   dEmcClusterLocalExt->set_tofmincorr(nPeakArea, tofmincorr);
00493                   dEmcClusterLocalExt->set_tofmax(nPeakArea, tofmax);
00494                   dEmcClusterLocalExt->set_etofmax(nPeakArea, etofmax);
00495                   dEmcClusterLocalExt->set_tofmaxcorr(nPeakArea, tofmaxcorr);
00496                   dEmcClusterLocalExt->set_tofmean(nPeakArea, 0);
00497                   dEmcClusterLocalExt->set_disp(0, nPeakArea, xx);
00498                   dEmcClusterLocalExt->set_disp(1, nPeakArea, yy);
00499                   dEmcClusterLocalExt->set_padisp(0, nPeakArea, padisp[0]);
00500                   dEmcClusterLocalExt->set_padisp(1, nPeakArea, padisp[1]);
00501 
00502                   dEmcClusterLocalExt->set_yz_cg(0, nPeakArea, xcg);
00503                   dEmcClusterLocalExt->set_yz_cg(1, nPeakArea, ycg);
00504 
00505                   float esum = 0;
00506                   for (ih = 0; ih < HITS_TO_TABLE; ih++)
00507                     {
00508                       if (HVect[ih].amp <= 0)
00509                         {
00510                           dEmcClusterLocalExt->set_twrlist(ih, nPeakArea, 0);
00511                           dEmcClusterLocalExt->set_partesum(ih, nPeakArea, 0);
00512 
00513                         }
00514                       else
00515                         {
00516                           ich = HVect[ih].ich;
00517                           iy = ich / Nx[is];
00518                           iz = ich - iy * Nx[is];
00519                           ind = iz + iy * 100 + 10000 * sector + 100000 * arm;
00520                           dEmcClusterLocalExt->set_twrlist(ih, nPeakArea, ind);
00521                           esum += HVect[ih].amp;
00522                           dEmcClusterLocalExt->set_partesum(ih, nPeakArea, 
00523                                                             esum);
00524                         }
00525                     }
00526 
00527                   dEmcClusterLocalExt->set_e9(nPeakArea, e9);
00528                   dEmcClusterLocalExt->set_re9(nPeakArea, re9);
00529 
00530                   // MV 2001/09/25
00531                   // as chi2_sh and prob_photon_sh fields are not used,
00532                   // we can use them to store ADC and TAC for the cluster
00533                   dEmcClusterLocalExt->set_chi2_sh(nPeakArea, hmax.adc);
00534                   dEmcClusterLocalExt->set_prob_photon_sh(nPeakArea, hmax.tac);
00535 
00536                   // MV 2001/12/06
00537                   dEmcClusterLocalExt->set_deadmap(nPeakArea, hmax.deadmap);
00538                   dEmcClusterLocalExt->set_warnmap(nPeakArea, hmax.warnmap);
00539 
00540                   nPeakArea++;
00541                 } // if e>eClustMin
00542               pp++;
00543             } // Finished looping over peak areas
00544           nCluster++;
00545         } // Finished looping over clusters
00546     } // is
00547 
00548   //==========> Finished looping over sectors <==========
00549   dEmcClusterLocalExt->SetRowCount(nPeakArea);
00550 
00551   return true;
00552 }
00553 
00554 void
00555 mEmcClusterNewModule::ToF_Process(EmcModule* phit, float dist, EmcModule& hmax,
00556                                   float* ptof, float* petof, float* ptofcorr,
00557                                   float* pdtof,
00558                                   float* ptofmin, float* petofmin, 
00559                                   float* ptofmincorr,
00560                                   float* ptofmax, float* petofmax, 
00561                                   float* ptofmaxcorr)
00562 {
00563   int i;
00564   float tof, tofcorr, etof, tflash;
00565   float tofmin, tofmincorr, etofmin, tofmax, tofmaxcorr, etofmax;
00566   EmcModule* ph;
00567 
00568   tof = hmax.tof;
00569   etof = hmax.amp;
00570 
00571   tofmax = 0;
00572   tofmin = 999;
00573   etofmax = 0;
00574   etofmin = 0;
00575   ph = phit;
00576 
00577   for (i = 0; i < HITS_TO_TABLE; i++)
00578     {
00579       if (ph->amp > 0)
00580         {
00581           if (ph->tof > tofmax)
00582             {
00583               tofmax = ph->tof;
00584               etofmax = ph->amp;
00585             }
00586           if (ph->tof < tofmin)
00587             {
00588               tofmin = ph->tof;
00589               etofmin = ph->amp;
00590             }
00591         }
00592       ph++;
00593     }
00594   tflash = dist / 30.0;
00595 
00596   tof = tof - tflash;
00597   tofmin = tofmin - tflash;
00598   tofmax = tofmax - tflash;
00599 
00600   tofcorr = tof;
00601   tofmincorr = tofmin;
00602   tofmaxcorr = tofmax;
00603 
00604   *ptof = tof;
00605   *petof = etof;
00606   *ptofcorr = tofcorr;
00607   *pdtof = 0;
00608   *ptofmax = tofmax;
00609   *petofmax = etofmax;
00610   *ptofmaxcorr = tofmaxcorr;
00611   *ptofmin = tofmin;
00612   *petofmin = etofmin;
00613   *ptofmincorr = tofmincorr;
00614 }