Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

TrackerRecon.cxx

Go to the documentation of this file.
00001 
00002 //-------------------------------------------------------------------
00003 //  $Header: /nfs/slac/g/glast/ground/cvs/reconstruction/src/TrackerRecon.cxx,v 1.13 2001/09/05 15:52:43 lsrea Exp $   */
00004 //
00005 //     TrackerRecon:
00006 //
00007 //          Steers the Silicon-Tracker Reconstruction    
00008 //
00009 //                    Bill Atwood
00010 //                    B. Atwood, JA Hernando, Santa Cruz, 02/05/99
00011 //
00012 //-------------------------------------------------------------------
00013 
00014 
00015 #include "reconstruction/TrackerRecon.h"
00016 #include "reconstruction/GlastRecon.h"
00017 /*
00018 #include "instrument/Glast.h"
00019 #include "instrument/Tower.h"
00020 #include "instrument/SiTracker.h"
00021 */
00022 #include "DetectorData.h"
00023 
00024 
00025 #include "reconstruction/ReconVisitor.h"
00026 #include "reconstruction/SiClusters.h"
00027 #include "reconstruction/GlastFit.h"
00028 #include "reconstruction/CalRecon.h"
00029 #include "reconstruction/MCRecon.h"
00030 
00031 // analysis function includes
00032 #include "reconstruction/ActiveDistance.h"
00033 #include "reconstruction/EnergyCorrection.h"
00034 #include "reconstruction/ExtraHits.h"
00035 #include "reconstruction/TowerBoundaries.h"
00036 #include "reconstruction/TrackerVeto.h"
00037 
00038 #include "gui/DisplayRep.h"
00039 
00040 #include <algorithm>
00041 
00042 #define MAX_NO_FITS 15
00043 #define Z_DISPLAY_LEN 50
00044 #define TEST_MIN 5.0
00045 #define IST_CHI2SELECT 10.0
00046 #define CHI2SELECT 250.
00047 #define RES1_CUT 10.
00048 #define RES2_CUT 5
00049 
00050 //#define MAX_NO_FITS 10
00051 //#define Z_DISPLAY_LEN 50
00052 //#define TEST_MIN 8.0
00053 //#define IST_CHI2SELECT 6.0
00054 //#define CHI2SELECT 50.
00055 //#define RES1_CUT 10.
00056 //#define RES2_CUT 5.
00057 
00058 //unused: static float testMax;
00059 //unused: static float firstPlaneWt;
00060 //unused: static int numFits;
00061 /*
00062 static bool kalPrivateTup = false;
00063 static int kalglast_event=0;
00064 static int kaltrack_event=0;
00065 static int kalplane_event=0; */
00066 
00067 // Update TrackerRecon
00068 static bool CONTROL_writeOut = false;
00069 static int CONTROL_debug = 2;
00070 static double CONTROL_sigmaCut = 8.; // 10.
00071 // following duplicates what is in GlastFit.cxx
00072 //unused: static bool                CONTROL_newReconstruction  = true;
00073 static double              CONTROL_minEnergy          = 0.03;
00074 // static GFdata::particle CONTROL_particle = GFdata::ELECTRON;
00075 // unused: static double CUTOFF_ENERGY=0.02f;
00076 // unused: static double FENE = 1.;   // 0.75-1;
00077 static double XENE = 0.6; // 0.66666-0.75;
00078 static unsigned int MAX_CANDIDATES = 4;
00079 // unused: static bool VETO = true;
00080 // static double MIN_QUALITY = 3.;
00081 // unused:static int MAX_ATTEMPTS = 16;
00082 
00083 static int CONTROL_maxGammaTries = 1;
00084 static int CONTROL_maxParticleTries = 15;
00085 static int CONTROL_maxConsecutiveGaps = 2;
00086 
00087 static double CONTROL_minQ = -100.;
00088 
00089 static double CONTROL_FEne = 2./3.;  // defoult 2/3.
00090 static double CONTROL_FEneGamma = 1.;
00091 static double CONTROL_FEneParticle = 1./3.;
00092 //unused: static double CUT_minQualityParticle = 0.;
00093 //unused: static double CONTROL_maxMoreTracks = 3;
00094 //unused: static double CONTROL_eneMoreTracks = 0.5;  // fraction of the energy given to the more tracks
00095 
00096 inline static double sqr(double x){return x*x;}
00097 
00098 using namespace std;
00099 
00100 // declare static class data members here
00101 TrackerRecon::Parameters TrackerRecon::s_parms; 
00102 
00103 // define a pointer to the s_parms data member in the local namespace
00104 namespace {
00105     const TrackerRecon::Parameters*   parms = &TrackerRecon::params();
00106     
00107 };
00108 
00109 // implement the TrackerRecon::Parameters class
00110 
00111 // initialize: sets up parameters from the various GLAST instrument
00112 //  and medium classes.
00113 void    TrackerRecon::Parameters::initialize ()
00114 {
00115     // initialize kluge parameter structure
00116     num_convs    = DetectorData::SiTracker::numTrays()-1;
00117     conv_gap     = DetectorData::SiTracker::traySpacing();
00118     si_thickness = DetectorData::SiTracker::siThickness();
00119     conv_rad_len = DetectorData::SiTracker::convRadLen(1);
00120     tower_width  = DetectorData::Tower::mod_width + 2.*DetectorData::Tower::wall_thickness + DetectorData::Glast::wall_gap;
00121 
00122 }
00123 
00124 void TrackerRecon::initialize()
00125 {
00126     
00127     // Silicon Hits
00128     i_Conv_Layer_Hits     = data.addElement("Cnv_Lyr_Hits");
00129     i_max_controller_hits = data.addElement("max_controller_hits");
00130     i_First_Conv_Layer    = data.addElement("fst_Cnv_Lyr");
00131     i_nConv_Layers_Hit    = data.addElement("nCnv_Lyrs_Hit");
00132     i_Conv_Layer_Hits_Gamma = data.addElement("Cnv_Hits_Gamma");
00133     i_nConv_Layers_Gamma    = data.addElement("nCnv_Lyrs_Gamma");
00134     i_First_Conv_Layer_Gamma = data.addElement("fst_Cnv_Lyr_Gamma");
00135     
00136     // Tracker Reconstruction
00137     i_Kal_Energy         = data.addElement("KalEne_Gamma");
00138     i_Kal_Energy_X       = data.addElement("KalEne_X");
00139     i_Kal_Energy_Y       = data.addElement("KalEne_Y");
00140     
00141     // Event Reconstruction
00142     i_No_XTrks            = data.addElement("No_X_Trks");
00143     i_No_YTrks            = data.addElement("No_Y_Trks");
00144     i_No_Trks             = data.addElement("No_Tracks");
00145     
00146     // Gamma quality
00147     i_fit_type            = data.addElement("Fit_Type");
00148     i_fit_topo            = data.addElement("Fit_Topo");
00149     i_Chisq_1st           = data.addElement("Chisq_1st");
00150     i_Chisq               = data.addElement("Chisq");
00151     i_No_Hits             = data.addElement("No_Trk_Hits");
00152     i_No_SHits            = data.addElement("Sum_Hits");
00153     i_No_Gaps             = data.addElement("Fit_Gaps");
00154     i_No_Gaps_1st         = data.addElement("First_Fit_Gaps");
00155     i_No_Noise            = data.addElement("Noise_Hits");
00156     i_No_Noise_1st        = data.addElement("First_Noise_Hits");
00157     i_qual_X              = data.addElement("X_Quality_Parm");
00158     i_qual_Y              = data.addElement("Y_Quality_Parm");
00159     i_qual                = data.addElement("Quality_Parm");
00160     
00161     // Pair reconstruction
00162     i_Fit_XNhits          = data.addElement("Fit_XNhits");
00163     i_Fit_YNhits          = data.addElement("Fit_YNhits");
00164     i_Fit_XChisq          = data.addElement("Fit_XChisq");
00165     i_Fit_YChisq          = data.addElement("Fit_YChisq");
00166     i_Fit_XChisq_1st      = data.addElement("Fit_XChisq_1st");
00167     i_Fit_YChisq_1st      = data.addElement("Fit_YChisq_1st");
00168     i_Fit_XKalThetaMS     = data.addElement("Fit_XKalTheta");
00169     i_Fit_YKalThetaMS     = data.addElement("Fit_YKalTheta");
00170     i_Fit_XKalEne         = data.addElement("Fit_XKalEne");
00171     i_Fit_YKalEne         = data.addElement("Fit_YKalEne");
00172     i_Fit_x0              = data.addElement("Fit_x0");
00173     i_Fit_y0              = data.addElement("Fit_y0");
00174     i_Fit_z0              = data.addElement("Fit_z0");
00175     i_Fit_xdir            = data.addElement("Fit_x_dir");
00176     i_Fit_ydir            = data.addElement("Fit_y_dir");
00177     i_Fit_zdir            = data.addElement("Fit_z_dir");
00178     
00179     i_Pair_XNhits         = data.addElement("Pair_XNhits");
00180     i_Pair_YNhits         = data.addElement("Pair_YNhits");
00181     i_Pair_XChisq         = data.addElement("Pair_XChisq");
00182     i_Pair_YChisq         = data.addElement("Pair_YChisq");
00183     i_Pair_XChisq_1st     = data.addElement("Pair_XChisq_1st");
00184     i_Pair_YChisq_1st     = data.addElement("Pair_YChisq_1st");
00185     i_Pair_XKalThetaMS    = data.addElement("Pair_XKalTheta");
00186     i_Pair_YKalThetaMS    = data.addElement("Pair_YKalTheta");
00187     i_Pair_XKalEne        = data.addElement("Pair_XKalEne");
00188     i_Pair_YKalEne        = data.addElement("Pair_YKalEne");
00189     i_Pair_x0             = data.addElement("Pair_x0");
00190     i_Pair_y0             = data.addElement("Pair_y0");
00191     i_Pair_z0             = data.addElement("Pair_z0");
00192     i_Pair_xdir           = data.addElement("Pair_x_dir");
00193     i_Pair_ydir           = data.addElement("Pair_y_dir");
00194     i_Pair_zdir           = data.addElement("Pair_z_dir");
00195     
00196     i_e_frac              = data.addElement("Energy_Split");
00197     i_errSlopeX           = data.addElement("KalErr_Xslope");
00198     i_errSlopeY           = data.addElement("KalErr_Yslope");
00199     i_weightXSlope        = data.addElement("weight_Xslope");
00200     i_weightYSlope        = data.addElement("weight_Yslope");
00201     i_xeneXSlope          = data.addElement("xene_Xslope");
00202     i_xeneYSlope          = data.addElement("yene_Yslope");      
00203     
00204     // gamma reconstruction
00205     i_First_XHit          = data.addElement("fst_X_Lyr");
00206     i_First_YHit          = data.addElement("fst_Y_Lyr");
00207     i_Diff_1st_Hit        = data.addElement("Diff_1st_XY_Lyr");
00208     i_Gamma_x0            = data.addElement("Gamma_x0");
00209     i_Gamma_y0            = data.addElement("Gamma_y0");
00210     i_Gamma_z0            = data.addElement("Gamma_z0");
00211     i_Gamma_xdir          = data.addElement("Gamma_x_dir");
00212     i_Gamma_ydir          = data.addElement("Gamma_y_dir");
00213     i_Gamma_zdir          = data.addElement("Gamma_z_dir");
00214     
00215     // analysis
00216     i_Gamma_DLT           = data.addElement("t_Angle");
00217     i_Zdiff_XY            = data.addElement("Zdiff_XY");
00218     i_Zdiff_plane         = data.addElement("Zdiff_plane");
00219     
00220     // HMA (GSFC) silicon hit clusters (within a tray) ntuple elements 6/3/1999
00221     i_FitSide_nXused      = data.addElement("FitSide_nXused");
00222     i_FitSide_nYused      = data.addElement("FitSide_nYused");
00223     
00224     // extra analysis JAH 7/9/99
00225     i_fit_kink = data.addElement("Fit_Kink");
00226     i_pair_kink = data.addElement("Pair_Kink");
00227     i_fit_kinkN = data.addElement("Fit_KinkN");
00228     i_pair_kinkN = data.addElement("Pair_KinkN");
00229     
00230     i_hits_previous = data.addElement("Hits_Previous");
00231     i_hits_first = data.addElement("Hits_First");
00232     i_hits_next = data.addElement("Hits_Next");
00233     
00234     _mclsData = new SiClusters(parms->num_convs);
00235     
00236     // now that the 'data' member is initialized,
00237     // set the data for all of the analysis variable objects.
00238     // note that the tracker recon object still 
00239     // creates these values as well - however only
00240     // to keep the tuple items in the same position in
00241     // the tuple 
00242     if(m_activeDist!=0) { // skip if not doing this junk
00243     m_activeDist->setData (&data);
00244     m_Ecorr->setData (&data);
00245     m_extraHits->setData (&data);
00246     m_twrBounds->setData (&data);
00247     m_tkrVeto->setData (&data);
00248     }
00249     _mGFgamma = 0;
00250 
00251 }
00252 
00253 TrackerRecon::TrackerRecon()
00254 : Recon(), cal(0), 
00255 m_activeDist(0), 
00256 m_Ecorr(0), 
00257 m_extraHits(0), 
00258 m_twrBounds(0),
00259 m_tkrVeto(0) 
00260 {
00261     setTitle("TrackerRecon");
00262     
00263     // initialize kluge parameter structure
00264     s_parms.initialize();
00265     initialize();
00266 }
00267  
00268 //######################################################
00269 TrackerRecon::TrackerRecon (GlastRecon* r)
00270 //###################################################
00271 : Recon(), cal(r->getCal())
00272 ,  m_activeDist(new ActiveDistance(r)), 
00273 m_Ecorr(new EnergyCorrection(r)), 
00274 m_extraHits(new ExtraHits(r)), 
00275 m_twrBounds(new TowerBoundaries(r)),
00276 m_tkrVeto(new TrackerVeto(r)) 
00277 {
00278     setTitle("TrackerRecon");
00279     
00280     // initialize kluge parameter structure
00281     s_parms.initialize();
00282     initialize();
00283 
00284 }
00285 
00286 //##############################################
00287 TrackerRecon::~TrackerRecon ()
00288 //##############################################
00289 {
00290     delete _mclsData;
00291     
00292     delete m_Ecorr;
00293     delete m_activeDist;
00294     delete m_extraHits;
00295     delete m_twrBounds;
00296     delete m_tkrVeto;
00297 }
00298 
00299 //##########################################################
00300 void TrackerRecon::accept (ReconVisitor& d) {d.visit(this);}
00301 //###########################################################
00302 
00303 //###################################
00304 void TrackerRecon::clear ()
00305 //###################################
00306 {
00307     Recon::clear();
00308     data.clear();
00309     
00310     if (_mGFgamma != 0) delete _mGFgamma;
00311     _mGFgamma = 0;
00312     
00313     xtrackList.clear();
00314     ytrackList.clear();
00315     
00316     _mclsData->clear();
00317 }
00318 
00319 //#########################################
00320 void TrackerRecon::draw (gui::DisplayRep& v)
00321 //#########################################
00322 {
00323     int nxtracks = xtrackList.size();
00324     int nytracks = ytrackList.size();
00325     
00326     // X-Tracks
00327     KalHit::TYPE type = KalHit::SMOOTH;
00328     int itrack=0;
00329     for (; itrack<nxtracks; itrack++){
00330         KalTrack xtrack = xtrackList[itrack];
00331         if( itrack ==0) v.setColor("blue");
00332         else v.setColor("navy");
00333         xtrack.drawTrack(v, SiData::X, type);
00334         xtrack.drawChiSq(v, SiData::X, type);
00335         
00336         if (CONTROL_writeOut) xtrack.writeOut(CONTROL_writeOut);
00337     }
00338     
00339     // Y-Tracks
00340     for (itrack=0; itrack<nytracks; itrack++){
00341         KalTrack ytrack = ytrackList[itrack];
00342         if( itrack ==0) v.setColor("blue");
00343         else v.setColor("navy");
00344         ytrack.drawTrack(v, SiData::Y, type);
00345         ytrack.drawChiSq(v, SiData::Y, type);
00346         
00347         if (CONTROL_writeOut) ytrack.writeOut(CONTROL_writeOut);
00348     }
00349 
00350     //Gamma
00351     if(_mGFgamma) {
00352         v.setColor("yellow");
00353         v.moveTo(_mGFgamma->vertex());
00354         v.lineTo(_mGFgamma->vertex() - 300.*_mGFgamma->direction());
00355     }
00356 
00357     v.setColor("black");
00358 }
00359 //---------------------------------------
00360 //   Voila, monsieur le reconstructeur
00361 //---------------------------------------
00362 //###########################################################
00363 void TrackerRecon::reconstruct(const SiData* stripData)
00364 //###########################################################
00365 {
00366     
00367     if(state() == DONE) return;
00368     
00369     RCreconstruct(stripData);
00370     
00371     
00372 }
00373 //--------------------------------------------------------
00374 //     Segmented Original TrackerRecon - Flow private fuctions
00375 //--------------------------------------------------------
00376 //########################################################
00377 void TrackerRecon::iniTrackerRecon()
00378 //########################################################
00379 {
00380     // Data Members for Associations
00381     x1 = Point(0.,0.,0.);
00382     t1 = Vector(0.,0.,0.);
00383     t0 = Vector(0.,0.,0.);
00384     x0 = Point(0.,0.,0.);
00385     
00386     m_totalHits = 0;
00387     m_firstConvLayer = -1;
00388     m_numLayersHit = 0;
00389     
00390     m_CsIEnergy = 0.;
00391     m_CsICorrEnergy = 0.;
00392     m_aveCalHit = Point(0.,0.,0.);
00393     
00394     
00395     m_firstLayer = -1;
00396     m_fitType = -1;
00397     m_xFactor = 0.;
00398     m_yFactor = 0.; 
00399     
00400     // clear all of the analysis objects here (if they were made)
00401     if( m_activeDist !=0 ) {
00402         m_activeDist->clear();
00403         m_Ecorr->clear();
00404         m_extraHits->clear();
00405         m_twrBounds->clear();
00406         m_tkrVeto->clear();
00407     }
00408 }
00409 //########################################################
00410 void TrackerRecon::iniClusters(const SiData* stripData)
00411 //########################################################
00412 {
00413     
00414     m_totalHits = 0;
00415     m_numLayersHit = 0;
00416     m_firstConvLayer = -1;
00417     
00418     int i;
00419     for(i=0; i<parms->num_convs; i++) {
00420         int hitCount = stripData->nHits(SiData::X, i) + stripData->nHits(SiData::Y, i);
00421         if(hitCount > 0) {
00422             if(m_firstConvLayer < 0) {
00423                 m_firstConvLayer = i;
00424             }
00425             m_totalHits+= hitCount;
00426             m_numLayersHit++;
00427         }
00428     }
00429     // Now make clusters for tracking
00430     _mclsData->loadFrom(*stripData);
00431 
00432     data.addData(i_Conv_Layer_Hits, m_totalHits);
00433 //THB    data.addData(i_max_controller_hits, stripData->maxControllerHits());
00434     data.addData(i_First_Conv_Layer, m_firstConvLayer);
00435     data.addData(i_nConv_Layers_Hit, m_numLayersHit);
00436     
00437     int iGammaLayer = 100;
00438     int nGammaHits = 0;
00439     int nGammaLayers = 0;
00440     int indexhit = -1;
00441     int jndexhit = -1;
00442     Point Dummy;
00443     for (i = m_firstConvLayer; i < parms->num_convs ; i++) {
00444         bool oklayer = false;
00445         // initialize X coordinate
00446         Dummy = _mclsData->nextHit(SiData::X, -1, &indexhit);
00447         do {
00448             Dummy = _mclsData->nextHit(SiData::X, i, &indexhit);
00449             if (indexhit > 0) {
00450                 if (_mclsData->clusterNoise(SiData::X, indexhit) == 0) {
00451                     nGammaHits++;
00452                     oklayer = true;
00453                 }
00454             }
00455         } while (indexhit >0);
00456         // initialize Y coordinate
00457         Dummy = _mclsData->nextHit(SiData::Y,-1, &jndexhit);
00458         do {
00459             Dummy = _mclsData->nextHit(SiData::Y, i, &jndexhit);
00460             if (jndexhit > 0) {
00461                 if (_mclsData->clusterNoise(SiData::Y,jndexhit) == 0) {
00462                     nGammaHits++;
00463                     oklayer = true;
00464                 }
00465             }
00466         } while (jndexhit >0);
00467         if (oklayer) {
00468             nGammaLayers++;
00469             if (i < iGammaLayer) iGammaLayer = i;
00470         }
00471     }
00472     
00473     data.addData(i_Conv_Layer_Hits_Gamma, nGammaHits);
00474     data.addData(i_First_Conv_Layer_Gamma, iGammaLayer);
00475     data.addData(i_nConv_Layers_Gamma, nGammaLayers);
00476 }
00477 
00478 //########################################################
00479 void TrackerRecon::iniCalorimeterInput()
00480 //########################################################
00481 {    
00482     m_CsIEnergy = 0.;
00483     m_CsICorrEnergy = 0.;
00484     m_aveCalHit = Point(0.,0.,0.);
00485     m_CsIEnergy = (double) cal->data.getData("CsI_Energy_Sum");
00486     m_CsICorrEnergy = m_CsIEnergy;
00487 
00488     // JAH 7/29/99
00489     // store this information for the moment
00490     // if there is no RC event in the tracker, at least the
00491     // corrected Energy is equal to the measured by the Calorimeter
00492     m_Ecorr->setCsIEnergy (m_CsICorrEnergy);
00493     
00494     // Note: Hit correction coef. depends on the radiator thickness and strip pitch
00495     //       and noise... present values are for 3.5% Pb, 200 um, and 5x10**-5 occup.
00496     m_CsICorrEnergy = m_CsIEnergy + 0.0006 * (m_totalHits - 55);
00497     if(m_CsIEnergy < .005) m_CsICorrEnergy = .025 + 0.0008 * (m_totalHits - 55);
00498     
00499 
00500     m_aveCalHit =Point(cal->data.getData("CsI_X"),
00501         cal->data.getData("CsI_Y"),
00502         cal->data.getData("CsI_Z"));
00503     
00504     // Dirty Only for e-quiet
00505     // m_CsIEnergy = (4./3.)*0.1;
00506 }
00507 
00508 //-----------------------------------------------------------
00509 //     Update TrackerRecon - for Pair Fit
00510 //-----------------------------------------------------------
00511 
00512 //###########################################################
00513 void TrackerRecon::RCreconstruct(const SiData* stripData)
00514 //###########################################################
00515 {
00516     
00517     //unused: int MAX_PAIRTRIES = 1;
00518     
00519     if(state() == DONE) return;
00520     
00521     iniTrackerRecon();    
00522     iniClusters(stripData);
00523     if(!(cal == 0)){
00524         iniCalorimeterInput();
00525     }
00526     
00527     GFtutor::_DATA = _mclsData;
00528     
00529     bool okRC = false;
00530     
00531     // Gamma reconstruction
00532     int ntries = 0;
00533     bool doit = true;
00534     while (ntries < CONTROL_maxGammaTries && doit) {
00535         ntries ++;
00536         bool seedOK = seedCandidates(GFdata::PAIR);
00537         bool gammaOK = false;
00538         if (seedOK) gammaOK = candidates(GFdata::GAMMA, GFdata::PAIR);
00539         if (gammaOK) selectGamma();
00540         else doit = false;
00541         okRC = okRC || gammaOK;
00542     } 
00543     
00544     // Other tracks reconstruction
00545     ntries = 0;
00546     doit = true; 
00547     while (ntries < CONTROL_maxParticleTries && doit) {
00548         GFtutor::CUT_veto = false;
00549         ntries ++;
00550         bool seedOK = seedCandidates(GFdata::TRACK);
00551         bool particleOK = false;
00552         if (seedOK) particleOK = candidates(GFdata::PARTICLE, GFdata::TRACK);
00553         if (particleOK) selectParticle();
00554         else doit = false;
00555         okRC = okRC || particleOK;
00556         GFtutor::CUT_veto = true;
00557     };
00558     
00559     if (okRC) loadTuple(stripData);
00560     // if (kalPrivateTup) KalPrivateTup();
00561 }
00562 
00563 //###########################################################
00564 bool TrackerRecon::seedCandidates(enum GFdata::type type)
00565 //###########################################################
00566 {
00567     bool ok = false;
00568     
00569     m_Xcandidates.clear();
00570     m_Ycandidates.clear();
00571     
00572     bool okX = findSeedCandidates(m_Xcandidates, type, SiData::X);
00573     bool okY = findSeedCandidates(m_Ycandidates, type, SiData::Y);
00574     
00575     if (okX || okY) ok = true; 
00576     return ok;
00577 }
00578 
00579 //###########################################################
00580 bool TrackerRecon::candidates(enum GFdata::type type, enum GFdata::type seedType)
00581 //###########################################################
00582 {
00583     bool OK = false;
00584     
00585     m_candidates.clear();
00586     
00587     unsigned int ix =0;
00588     unsigned int iy =0;
00589     for (; ix < m_Xcandidates.size(); ix++) {
00590         for (; iy < m_Ycandidates.size(); iy++) {
00591             GFdata Xcandidate = m_Xcandidates[ix];
00592             GFdata Ycandidate = m_Ycandidates[iy];
00593             bool ok = false;
00594             ok = findCandidates(m_candidates, Xcandidate, Ycandidate, type);
00595             OK = OK || ok;
00596         } // Y candidates
00597     } // X candidates  
00598     
00599     if (OK) return OK;
00600     
00601     // Force a PairFit with no veto
00602     bool save_veto = GFtutor::CUT_veto;
00603     std::vector<GFdata> candidates;
00604     candidates.clear();
00605     for (ix = 0 ; ix < m_Xcandidates.size(); ix++) {
00606         GFdata Xcandidate = m_Xcandidates[ix];
00607         candidates.clear();
00608         GFtutor::CUT_veto = false;
00609 
00610         findSeedCandidates(candidates, seedType, SiData::Y,Xcandidate.firstLayer(),Xcandidate.tower());
00611         for (iy =0 ; iy < candidates.size(); iy++) {
00612             GFtutor::CUT_veto = save_veto;
00613             GFdata Ycandidate = candidates[iy];
00614             bool ok = findCandidates(m_candidates,Xcandidate,Ycandidate, type);
00615             OK = OK || ok;
00616         } // Y candidates
00617     } // X candidates
00618     
00619     candidates.clear();
00620     for (iy = 0 ; iy < m_Ycandidates.size(); iy++) {
00621         GFdata Ycandidate = m_Ycandidates[iy];
00622         candidates.clear();
00623         GFtutor::CUT_veto = false;
00624 
00625         findSeedCandidates(candidates, seedType, SiData::X,Ycandidate.firstLayer(),Ycandidate.tower());
00626         for (ix =0 ; ix < candidates.size(); ix++) {
00627             GFtutor::CUT_veto = save_veto;
00628             GFdata Xcandidate = candidates[ix];
00629             bool ok = findCandidates(m_candidates,Xcandidate,Ycandidate, type);
00630             OK = OK || ok;
00631         } // Y candidates
00632     } // X candidates
00633     GFtutor::CUT_veto = save_veto;
00634     return OK;
00635 }
00636 
00637 //###########################################################
00638 bool TrackerRecon::findCandidates(std::vector<GFdata>& candidates,
00639                                   const GFdata& Xcandidate, const GFdata& Ycandidate,
00640                                   enum GFdata::type type)
00641                                   //###########################################################
00642 {
00643     bool ok = false;
00644     int naccepted = 0;
00645     
00646     int iniLayer = (Xcandidate.firstLayer() < Ycandidate.firstLayer()?
00647         Xcandidate.firstLayer() : Ycandidate.firstLayer());
00648     int lastLayer = (Xcandidate.firstLayer()< Ycandidate.firstLayer()?
00649         Ycandidate.firstLayer() : Xcandidate.firstLayer());
00650     
00651     if (lastLayer - iniLayer >= CONTROL_maxConsecutiveGaps) return ok;
00652     
00653     Point ver =GFdata::doVertex(Xcandidate.ray(),Ycandidate.ray());
00654     Vector dir = GFdata::doDirection(Xcandidate.direction(),Ycandidate.direction());
00655     Ray testRay(ver, dir);
00656     //unused:   int nhits = Xcandidate.nhits()+Ycandidate.nhits();
00657     //m_CsICorrEnergy = m_CsIEnergy + corrEnergy(nhits,0.);
00658     
00659     for (int ilayer = iniLayer ; ilayer <= lastLayer; ilayer++) {
00660 
00661         GFdata candidateGFdata = GFconstructor(type, ilayer, testRay);
00662         if (candidateGFdata.Q() > CONTROL_minQ) {
00663             ok = true;
00664             naccepted++;
00665             incorporate(candidates, candidateGFdata);
00666         }
00667     }
00668     
00669     return ok;
00670 }
00671 
00672 //###########################################################
00673 GFdata TrackerRecon::GFconstructor(enum GFdata::type type, int ilayer, 
00674                                    const Ray testRay, SiData::Axis axis)
00675                                    //###########################################################
00676 {
00677     GFdata data;
00678 
00679     if (type == GFdata::PARTICLE) {
00680         GFparticle* _par = new GFparticle(CONTROL_sigmaCut,
00681             CONTROL_FEneParticle*m_CsICorrEnergy, ilayer, testRay);
00682         if (!_par->empty() && _par->accept()) data = _par->getGFdata();
00683         delete _par;
00684     } else if (type == GFdata::GAMMA) {
00685         GFgamma* _gamma = new GFgamma(CONTROL_FEne, CONTROL_sigmaCut,
00686             m_CsICorrEnergy, ilayer, testRay);
00687         if (!_gamma->empty() && _gamma->accept()) {
00688             data = _gamma->getGFdata();
00689         }
00690         delete _gamma;
00691     } else if (type == GFdata::TRACK) {
00692         GFtrack* _track = new GFtrack(axis, CONTROL_sigmaCut, 
00693             CONTROL_FEneParticle*m_CsICorrEnergy, ilayer, testRay);
00694         if (!_track->empty() && _track->accept()) data = _track->getGFdata();
00695         delete _track;
00696     } else if (type == GFdata::PAIR) {
00697         GFpair* _pair = new GFpair(CONTROL_FEne, axis, CONTROL_sigmaCut,
00698             CONTROL_FEneGamma*m_CsICorrEnergy, ilayer, testRay);
00699         if (!_pair->empty()) {
00700             if (_pair->accept()) {
00701                 data = _pair->getBest()->getGFdata();
00702             }
00703         }
00704         delete _pair;
00705     } 
00706     
00707     return data;
00708 }
00709 //###########################################################
00710 void TrackerRecon::selectGamma()
00711 //###########################################################
00712 {
00713     
00714     if (_mGFgamma != 0) delete _mGFgamma;
00715     _mGFgamma = 0;
00716     
00717     GFdata gammaCandidate = m_candidates[0];
00718     
00719     int iniLayer = gammaCandidate.firstLayer();
00720     Ray testRay = gammaCandidate.ray();
00721     
00722     //unused:   int nhits = gammaCandidate.nhits();
00723     // m_CsICorrEnergy = m_CsIEnergy + corrEnergy(nhits,0.);
00724     
00725     _mGFgamma = new GFgamma(CONTROL_FEne, CONTROL_sigmaCut,
00726         m_CsICorrEnergy, iniLayer, testRay);
00727     
00728     if (CONTROL_writeOut && !_mGFgamma->empty()) _mGFgamma->writeOut(CONTROL_debug);
00729     
00730     loadTrackerRecon();
00731     
00732     _mGFgamma->flagAllHits();
00733     
00734 }
00735 //###########################################################
00736 void TrackerRecon::selectParticle()
00737 //###########################################################
00738 {
00739     
00740     GFdata candidate = m_candidates[0];
00741     
00742     int iniLayer = candidate.firstLayer();
00743     Ray testRay = candidate.ray();
00744     
00745     //unused:   int nhits = candidate.nhits();
00746     // m_CsICorrEnergy = m_CsIEnergy + corrEnergy(nhits,0.);
00747     
00748     GFparticle* _GFparticle = new GFparticle(CONTROL_sigmaCut, 
00749         CONTROL_FEneParticle*m_CsICorrEnergy, iniLayer, testRay);
00750     
00751     if (_GFparticle->Q() > CONTROL_minQ) {
00752         if (!_GFparticle->getXGFtrack()->empty()) {
00753             xtrackList.push_back(
00754                 _GFparticle->getXGFtrack()->getKalTrack());
00755         }
00756         if (!_GFparticle->getYGFtrack()->empty()) {
00757             ytrackList.push_back(
00758                 _GFparticle->getYGFtrack()->getKalTrack());
00759         }
00760     }
00761     _GFparticle->flagAllHits();
00762     
00763     delete _GFparticle;
00764 }
00765 
00766 //###########################################################
00767 void TrackerRecon::loadTrackerRecon()
00768 //###########################################################
00769 {
00770     m_firstLayer = _mGFgamma->firstLayer();
00771     m_fitType = 0; // need some work
00772     m_xFactor =XENE;
00773     m_yFactor = XENE;
00774     
00775     x1 = GFdata::doVertex(_mGFgamma->getBest(SiData::X)->ray(),
00776         _mGFgamma->getBest(SiData::Y)->ray());
00777     t1 = GFdata::doDirection(_mGFgamma->getBest(SiData::X)->direction(),
00778         _mGFgamma->getBest(SiData::Y)->direction());
00779     
00780     if (!_mGFgamma->getPair(SiData::X)->empty() && !_mGFgamma->getPair(SiData::Y)->empty()) {
00781         x2 = GFdata::doVertex(_mGFgamma->getPair(SiData::X)->ray(),
00782             _mGFgamma->getPair(SiData::Y)->ray());
00783         t2 = GFdata::doDirection(_mGFgamma->getPair(SiData::X)->direction(),
00784             _mGFgamma->getPair(SiData::Y)->direction());
00785     } else {
00786         x2 = x1;
00787         t2 = t1;
00788     }
00789     
00790     x0 = _mGFgamma->vertex();
00791     t0 = _mGFgamma->direction();
00792     
00793     
00794     if (!_mGFgamma->getBest(SiData::X)->empty()) xtrackList.push_back(
00795         _mGFgamma->getBest(SiData::X)->getKalTrack());
00796     if (!_mGFgamma->getPair(SiData::X)->empty()) xtrackList.push_back(
00797         _mGFgamma->getPair(SiData::X)->getKalTrack());
00798     
00799     if (!_mGFgamma->getBest(SiData::Y)->empty()) ytrackList.push_back(
00800         _mGFgamma->getBest(SiData::Y)->getKalTrack());
00801     if (!_mGFgamma->getPair(SiData::Y)->empty()) ytrackList.push_back(
00802         _mGFgamma->getPair(SiData::Y)->getKalTrack());
00803     
00804 }
00805 
00806 //---------------------------------------------------------
00807 //     Update TrackerRecon - for GlastFit - Second level
00808 //---------------------------------------------------------
00809 
00810 //###########################################################
00811 bool TrackerRecon::findSeedCandidates(std::vector<GFdata>& candidates, GFdata::type type, SiData::Axis axis)
00812 //###########################################################
00813 {
00814     bool OK = false;   
00815     int indexhit = -1;
00816     Point PIni = _mclsData->nextHit(axis, -1, &indexhit); 
00817     
00818     int ilayer=m_firstConvLayer;
00819 
00820     for ( ; ilayer < DetectorData::SiTracker::numTrays()-3; ilayer++){
00821         bool ok = findSeedCandidates(candidates, type, axis, ilayer);
00822         OK = OK || ok;
00823     }
00824     return OK;
00825 }
00826 
00827 //###########################################################
00828 bool TrackerRecon::findSeedCandidates(std::vector<GFdata>& candidates, GFdata::type type, 
00829                                       SiData::Axis axis, int ilayer, int itower)
00830 //###########################################################
00831 {
00832     //unused:   int nconstructed = 0;
00833     int naccepted = 0;
00834     bool ok = false;
00835     
00836     if (ilayer >= DetectorData::SiTracker::numTrays()-3) return ok;
00837     
00838     // Initialize tray
00839     int indexhit = -1;
00840     Point PIni = _mclsData->nextHit(axis, -1, &indexhit); 
00841     
00842     Point PRef;
00843     if (m_CsIEnergy > CONTROL_minEnergy) PRef = m_aveCalHit;
00844     
00845     int ihit=0;
00846     int nhitsInLayer = _mclsData->nHits(axis,ilayer);
00847 
00848     //PRef.printOn(std::cout);
00849     //std::cout << "\n";
00850 
00851     for ( ; ihit<nhitsInLayer; ihit++) {
00852         // Get Initial Point
00853         PIni = _mclsData->nextHit(axis,ilayer,&indexhit);
00854 
00855         if (indexhit<0)  {
00856             break;
00857         }        
00858         if (SiClusters::tower(indexhit) != itower && itower != 0) {
00859             continue;
00860         }
00861         
00862         // Get Reference Point
00863         //  if (PRef.mag() == 0. || m_CsIEnergy <= CONTROL_minEnergy)
00864         PRef = createPRef(axis, ilayer, PIni);
00865 
00866         // Get GFpair within layer, PIni and PRef - Inputs
00867         if (PIni.mag() == 0. || PRef.mag() == 0.)  {
00868             continue;
00869         }
00870 
00871         
00872         Vector VDir(PRef.x()-PIni.x(),PRef.y()-PIni.y(),PRef.z()-PIni.z());
00873         Ray testRay = Ray(PIni, VDir.unit());
00874         
00875         GFdata candidateGFdata = GFconstructor(type, ilayer, testRay, axis);
00876         
00877         if (candidateGFdata.Q() > CONTROL_minQ) {
00878             ok = true;
00879             naccepted++;
00880             incorporate(candidates, candidateGFdata);
00881         }
00882     }
00883     
00884     if (naccepted > 0) ok = true;
00885     return ok;
00886     
00887 }
00888 //###########################################################
00889 void TrackerRecon::incorporate(std::vector<GFdata>& pDatalist, const GFdata pData)
00890 //###########################################################
00891 {
00892     bool ienter = false;
00893     for (unsigned int i =0; i < pDatalist.size(); i++) {
00894         if (pData.Q() >= pDatalist[i].Q()) {
00895             pDatalist.insert(&pDatalist[i],pData);
00896             ienter = true;
00897         }
00898         if (ienter) break;
00899     }
00900     if (!ienter) pDatalist.push_back(pData);
00901     if (pDatalist.size()>MAX_CANDIDATES) pDatalist.pop_back();
00902     
00903 }
00904 //########################################################
00905 Point TrackerRecon::createPRef(SiData::Axis axis,int ilayer, const Point& Pini)
00906 //########################################################
00907 {
00908     double weight = CONTROL_minEnergy/(3.*m_CsICorrEnergy); // weight;
00909     
00910     Point PCal = m_aveCalHit;
00911 
00912     if (m_CsIEnergy < CONTROL_minEnergy) weight = 1.;
00913     if (PCal.mag() == 0) weight = 1.;
00914     Point PTrk = _mclsData -> meanHitInside(ilayer+1, s_parms.tower_width, Pini);
00915 
00916     if (PTrk.mag() == 0.) {
00917         PTrk = _mclsData -> meanHitInside(ilayer+2, s_parms.tower_width, Pini);  
00918     }
00919     if (PTrk.mag() == 0.) weight = 0.;
00920     double x = (1.-weight)*PCal.x()+weight*PTrk.x();  
00921     double y = (1.-weight)*PCal.y()+weight*PTrk.y();  
00922     double z = (1.-weight)*PCal.z()+weight*PTrk.z();
00923 
00924     Point PRef(x,y,z);
00925 
00926     if (PRef.mag() != 0.) {
00927         if (axis == SiData::X ) y = Pini.y();
00928         else x = Pini.x();
00929     } else {
00930         x = Pini.x();
00931         y = Pini.y();
00932         z = Pini.z()-DetectorData::SiTracker::traySpacing();
00933     }
00934     PRef = Point(x,y,z);
00935 
00936     return PRef;
00937 } 
00938 //--------------------------------------------------------
00939 //     Kalman Private Ntuple - Debug Version
00940 //--------------------------------------------------------
00941 //########################################################
00942 void TrackerRecon::loadTuple(const SiData* _stripData)
00943 //########################################################
00944 {           
00945     // Load results into data array
00946     //-----------------------------
00947     
00948     data.addData(i_No_XTrks, xtrackList.size());
00949     data.addData(i_No_YTrks, ytrackList.size());
00950     data.addData(i_No_Trks,  xtrackList.size() +ytrackList.size());
00951     
00952     if (_mGFgamma == 0) return;
00953     if (_mGFgamma->empty()) return;
00954     
00955     GFtrack* _Xbest = _mGFgamma->getXpair()->getBest();
00956     GFtrack* _Ybest = _mGFgamma->getYpair()->getBest();
00957     
00958     data.addData(i_Kal_Energy,_mGFgamma->RCenergy());
00959     data.addData(i_Kal_Energy_X, _mGFgamma->getXpair()->RCenergy());
00960     data.addData(i_Kal_Energy_Y, _mGFgamma->getYpair()->RCenergy());
00961     
00962     // data.add(i_TRC_code, 10*xtrackList.size()+ytrackList.size()); 
00963     
00964     // Gamma quality
00965     double type = 0;
00966     if (!_mGFgamma->empty()) type = 11;
00967     if (!_mGFgamma->getPair(SiData::X)->empty()) type += 1;
00968     if (!_mGFgamma->getPair(SiData::Y)->empty()) type += 10;
00969     data.addData(i_fit_type, type);
00970     
00971     double topo = 0;
00972     if (_mGFgamma->fix()) topo = 1.;
00973     if (_mGFgamma->conflictPattern()) topo *= -1.;
00974     data.addData(i_fit_topo, topo);
00975     
00976     data.addData(i_Chisq , _Xbest->chiSquare() + _Ybest->chiSquare());
00977     data.addData(i_Chisq_1st , _Xbest->chiSquareSegment() + _Ybest->chiSquareSegment());
00978     data.addData(i_qual_X ,_Xbest->Q());
00979     data.addData(i_qual_Y ,_Ybest->Q());
00980     data.addData(i_qual ,  _Xbest->Q() + _Ybest->Q());
00981     data.addData(i_No_Hits, _Xbest->numDataPoints()+_Ybest->numDataPoints());
00982     data.addData(i_No_Gaps, _Xbest->numGaps()+_Ybest->numGaps());
00983     data.addData(i_No_Gaps_1st,  _Xbest->numFirstGaps()+_Ybest->numFirstGaps());
00984     data.addData(i_No_Noise      ,_Xbest->numNoise()+_Ybest->numNoise());
00985     data.addData(i_No_Noise_1st  ,_Xbest->numFirstNoise()+_Ybest->numFirstNoise());
00986     
00987     int nxhits = _Xbest->numDataPoints();
00988     int nyhits = _Ybest->numDataPoints();
00989     
00990     if (!_mGFgamma->getXpair()->getPair()->empty()) {
00991         int nhits = _mGFgamma->getXpair()->getPair()->numDataPoints();
00992         if (nhits < nxhits) nxhits = nhits;
00993     }
00994     if (!_mGFgamma->getYpair()->getPair()->empty()) {
00995         int nhits = _mGFgamma->getYpair()->getPair()->numDataPoints();
00996         if (nhits< nyhits) nyhits = nhits;
00997     }
00998 
00999     // Pair reconstruction
01000     data.addData(i_Fit_XNhits ,_Xbest->nhits());
01001     data.addData(i_Fit_YNhits ,_Ybest->nhits());
01002     data.addData(i_Fit_XChisq ,_Xbest->chiSquare());
01003     data.addData(i_Fit_YChisq ,_Ybest->chiSquare());
01004     data.addData(i_Fit_XChisq_1st ,_Xbest->chiSquareSegment());
01005     data.addData(i_Fit_YChisq_1st ,_Ybest->chiSquareSegment());
01006     //data.addData(i_Fit_XChisq_Com ,_Xbest->computeChiSqSegment(nxhits));
01007     //data.addData(i_Fit_YChisq_Com ,_Ybest->computeChiSqSegment(nyhits));
01008     data.addData(i_Fit_XKalEne ,_Xbest->RCenergy());
01009     data.addData(i_Fit_YKalEne ,_Ybest->RCenergy());
01010     data.addData(i_Fit_XKalThetaMS ,_Xbest->KalThetaMS());
01011     data.addData(i_Fit_YKalThetaMS ,_Ybest->KalThetaMS());
01012     data.addData(i_Fit_xdir,  t1.x());
01013     data.addData(i_Fit_ydir,  t1.y());
01014     data.addData(i_Fit_zdir,  t1.z());
01015     data.addData(i_Fit_x0,    x1.x());
01016     data.addData(i_Fit_y0,    x1.y());
01017     data.addData(i_Fit_z0,    x1.z());
01018     
01019     GFtrack* _Xpair = _mGFgamma->getXpair()->getPair();
01020     GFtrack* _Ypair = _mGFgamma->getYpair()->getPair();
01021 
01022     if (!_Xpair->empty()) {
01023         data.addData(i_Pair_XNhits ,_Xpair->nhits());
01024         data.addData(i_Pair_XChisq ,_Xpair->chiSquare());
01025         data.addData(i_Pair_XChisq_1st ,_Xpair->chiSquareSegment());
01026 //        data.addData(i_Pair_XChisq_Com ,_Xpair->computeChiSqSegment(nxhits));
01027         data.addData(i_Pair_XKalEne ,_Xpair->RCenergy());
01028         data.addData(i_Pair_XKalThetaMS ,_Xpair->KalThetaMS());
01029     }
01030     if (!_Ypair->empty()) {
01031         data.addData(i_Pair_YNhits ,_Ypair->nhits());
01032         data.addData(i_Pair_YChisq ,_Ypair->chiSquare());
01033         data.addData(i_Pair_YChisq_1st ,_Ypair->chiSquareSegment());
01034 //        data.addData(i_Pair_YChisq_Com ,_Ypair->computeChiSqSegment(nyhits));
01035         data.addData(i_Pair_YKalEne ,_Ypair->RCenergy());        
01036         data.addData(i_Pair_YKalThetaMS ,_Ypair->KalThetaMS());
01037     }
01038     data.addData(i_Pair_x0,  x2.x());
01039     data.addData(i_Pair_y0,  x2.y());
01040     data.addData(i_Pair_z0,  x2.z());
01041     data.addData(i_Pair_xdir,  t2.x());
01042     data.addData(i_Pair_ydir,  t2.y());
01043     data.addData(i_Pair_zdir,  t2.z());
01044     
01045     data.addData(i_Gamma_xdir,t0.x());
01046     data.addData(i_Gamma_ydir,t0.y());
01047     data.addData(i_Gamma_zdir,t0.z());  
01048     data.addData(i_Gamma_x0,  x0.x());
01049     data.addData(i_Gamma_y0,  x0.y());
01050     data.addData(i_Gamma_z0,  x0.z());
01051     
01052     data.addData(i_e_frac, (m_xFactor+m_yFactor)/2.);
01053     data.addData(i_errSlopeX,     _mGFgamma->getXpair()->errorSlope());             
01054     data.addData(i_errSlopeY,     _mGFgamma->getYpair()->errorSlope());            
01055     data.addData(i_xeneXSlope,    _mGFgamma->getXpair()->RCenergy());   
01056     data.addData(i_xeneYSlope,    _mGFgamma->getYpair()->RCenergy());      
01057     data.addData(i_weightXSlope,  _mGFgamma->getXpair()->weightSlope());        
01058     data.addData(i_weightYSlope,  _mGFgamma->getYpair()->weightSlope());          
01059     
01060     float sinDLT = sqrt(std::max(0.0,(1. - sqr(t0*t1))));
01061     data.addData(i_Gamma_DLT, sinDLT);
01062     
01063     //  First Used Layer and previous Hits...
01064     int x_layer = _Xbest->firstLayer();
01065     data.addData(i_First_XHit, x_layer);
01066     int y_layer = _Ybest->firstLayer();
01067     int diffXY = x_layer - y_layer;
01068     data.addData(i_Diff_1st_Hit, diffXY);
01069     
01070     // Tracker Recon Analysis Variables
01071     //----------------------------------
01072     
01073     // compute the tracker veto parameters
01074 
01075     // ******* Take Note *******
01076     if(cal == 0){
01077         return;
01078     }
01079     m_tkrVeto->compute();
01080     
01081     // compute the tower/track boundary parameters
01082     m_twrBounds->compute();
01083     
01084     // compute the "Active_Dist" parameter
01085     m_activeDist->compute();
01086     
01087     double Zdiff_XY= _mGFgamma->getXpair()->vertex().z()-_mGFgamma->getYpair()->vertex().z();
01088     data.addData(i_Zdiff_XY, Zdiff_XY);
01089     Point firstHit = _mGFgamma->getFirstHit();
01090     double Zdiff_plane = _mGFgamma->vertex().z()-firstHit.z();
01091     data.addData(i_Zdiff_plane,Zdiff_plane);
01092     
01093     // compute the extra hits parameters
01094     m_extraHits->compute();
01095     
01096     // compute the CsI corrected energy
01097     m_Ecorr->compute();
01098     
01099     // make sure the data member for the CsICorrEnergy is set...
01100     m_CsICorrEnergy = m_Ecorr->result()->energyCorr();
01101     
01102     // kink in the first segment
01103     double fitkink,pairkink,fitkinkN,pairkinkN;
01104     fitkink = TAna_kink(pairkink, fitkinkN, pairkinkN);
01105     data.addData(i_fit_kink,fitkink);
01106     data.addData(i_pair_kink,pairkink);
01107     data.addData(i_fit_kinkN,fitkinkN);
01108     data.addData(i_pair_kinkN,pairkinkN);
01109     
01110     // hits in the previos and next plane
01111     double previousHits, firstHits, nextHits;
01112     firstHits = TAna_densityHits(previousHits, nextHits);
01113     data.addData(i_hits_previous,previousHits);
01114     data.addData(i_hits_first,firstHits);
01115     data.addData(i_hits_next,nextHits);
01116 }
01117 
01118 //########################################################
01119 double TrackerRecon::TAna_trackerVeto(double& xsigma, double& ysigma)
01120 //########################################################
01121 {
01122     // X view
01123     GFtrack* _Xbest = _mGFgamma->getXpair()->getBest();
01124     GFtrack* _Ybest = _mGFgamma->getYpair()->getBest();
01125     
01126     int indexhit;
01127     bool Xveto = _Xbest->veto(indexhit,xsigma);
01128     bool Yveto = _Ybest->veto(indexhit,ysigma);
01129     
01130     double icode = 0;
01131     if (Xveto) icode = 1;
01132     if (Yveto) icode += 2;
01133     return icode;
01134 }
01135 //########################################################
01136 double TrackerRecon::TAna_kink(double& pairKink, double& fitKinkN, double& pairKinkN)
01137 //########################################################
01138 {
01139     double fitKink = 0.;
01140     pairKink = 0.;
01141     
01142     GFtrack* xtrk = _mGFgamma->getBest(SiData::X);
01143     GFtrack* ytrk = _mGFgamma->getBest(SiData::Y);
01144     
01145     if (xtrk->empty() || ytrk->empty()) return fitKink;
01146     
01147     double xkink = xtrk->kink(0);
01148     double ykink = ytrk->kink(0);
01149     fitKink = (fabs(ykink) > fabs(xkink)? ykink:xkink);
01150     
01151     double xkinkN = xtrk->kinkNorma(0);
01152     double ykinkN = ytrk->kinkNorma(0);
01153     fitKinkN = (fabs(ykinkN) > fabs(xkinkN)? ykinkN:xkinkN);
01154     
01155     // Pair Track
01156     xtrk = _mGFgamma->getPair(SiData::X);
01157     ytrk = _mGFgamma->getPair(SiData::Y);
01158     
01159     if (xtrk->empty() || ytrk->empty()) return fitKink;
01160     
01161     xkink = xtrk->kink(0);
01162     ykink = ytrk->kink(0);
01163     pairKink = (fabs(ykink) > fabs(xkink)? ykink:xkink);
01164     
01165     xkinkN = xtrk->kinkNorma(0);
01166     ykinkN = ytrk->kinkNorma(0);
01167     pairKinkN = (fabs(ykinkN) > fabs(xkinkN)? ykinkN:xkinkN);
01168     
01169     return fitKink;
01170 }
01171 //########################################################
01172 double TrackerRecon::TAna_densityHits(double& previousHits, double& nextHits)
01173 //########################################################
01174 {
01175     double firstHits = 0.;
01176     previousHits = 0.;
01177     nextHits = 0.;
01178     
01179     //  Find number of hits around first hit: 5 sigma 
01180     
01181     // get the geometrical Factors
01182     int firstLayer = _mGFgamma->firstLayer();
01183     Point firstHit = _mGFgamma->vertex();
01184     //unused:   int diffXY = _mGFgamma->getXpair()->firstLayer()-_mGFgamma->getYpair()->firstLayer();
01185     //unused:   float dz    =  _mGFgamma->getBest(SiData::X)->vertex().z() - 
01186     //unused:           _mGFgamma->getBest(SiData::Y)->vertex().z();
01187     
01188     float hitRadFact = fabs(t0.z()) + sqrt(1. - t0.z()*t0.z())/fabs(t0.z());
01189     if(hitRadFact > 3.) hitRadFact = 3.;
01190     int ipln = parms->num_convs - firstLayer; 
01191     float radLenEff = (DetectorData::SiTracker::convRadLen(ipln) + 2.*parms->si_thickness/9.36 +.003)/fabs(t1.z());
01192     //unused:    float thetaCone = .014/(m_CsICorrEnergy/2.)*sqrt(radLenEff)*(1.+.038*log(radLenEff));
01193     //unused:    float minSprd  = 5.* thetaCone * parms->conv_gap; // 5 sigma cut
01194     //unused:    float dltSprd  = minSprd;
01195     float norm = sqrt(t0.x()*t0.x() + t0.y()*t0.y());
01196     float xFact = 1., yFact = 1.;
01197     if(norm > 10000.*FLT_MIN) {
01198         xFact = 1. + (hitRadFact - 1.)*fabs(t0.x())/norm;
01199         yFact = 1. + (hitRadFact - 1.)*fabs(t0.y())/norm;
01200     }
01201     //unused:    float dltX = dltSprd*xFact;
01202     //unused:    float dltY = dltSprd*yFact;
01203     
01204     float deltaS = parms->conv_gap/fabs(t0.z());
01205     
01206     // previous
01207     int iplane = -1;
01208     int i;
01209     for (i=std::max(firstLayer-1,0);i<=firstLayer+1;i++) {
01210         ipln = parms->num_convs - i;
01211         radLenEff +=  (DetectorData::SiTracker::convRadLen(ipln) + 2.*parms->si_thickness/9.36 +.003)/fabs(t1.z());
01212         float thetaMS = .014/(m_CsICorrEnergy/2.)*sqrt(radLenEff)*(1.+.038*log(radLenEff));
01213         float s_total = (i-firstLayer) * deltaS;
01214         float xSprd = thetaMS * deltaS * xFact * 2.021; // = 3.5 sigma/sqrt(3)
01215         float ySprd = thetaMS * deltaS * yFact * 2.021;
01216         Point trkHit((Point)(s_total*t0 + x0));
01217         if (xSprd > 50) xSprd = 50.;
01218         if (ySprd > 50) ySprd = 50.;
01219         float nearHits = -1.;
01220         if (i>=0) nearHits = _mclsData->numberOfHitsNear(i, xSprd, ySprd, trkHit);
01221         iplane++;
01222         if (iplane == 0) previousHits = nearHits;
01223         else if (iplane == 1) firstHits = nearHits;
01224         else if (iplane == 2) nextHits = nearHits;
01225     }
01226     
01227     return firstHits;
01228 }
01229 //########################################################
01230 double TrackerRecon::TAna_towerBoundary(double& xborder, double& yborder)
01231 //########################################################
01232 {
01233     
01234 /*
01235 double x_ist=0;
01236 double y_ist=0;
01237 double z_ist=0;
01238 z_ist = (_Xbest->getHit(0).z() > _Ybest->getHit(0).z()) ?
01239 _Xbest->getHit(0).z() : _Ybest->getHit(0).z();
01240 
01241   float dz    =  _Xbest->getHit(0).z() - _Ybest->getHit(0).z();
01242   if(dz > 0.) {
01243   x_ist = _Xbest->getHit(0).x();
01244   y_ist = _Ybest->getHit(0).x() + t0.y()*dz/t0.z();
01245   }
01246   else {
01247   x_ist = _Xbest->getHit(0).x() - t0.x()*dz/t0.z();
01248   y_ist = _Ybest->getHit(0).x();
01249   }
01250   Point firstHit = Point(x_ist, y_ist, z_ist);
01251   Point vertex = x0 + t0*(z_ist/t0.z());
01252     m_firstLayer = (x_layer < y_layer) ? x_layer : y_layer; */
01253     // unused:  double border = 0.;
01254     
01255     Point vertex = _mGFgamma->getFirstHit();
01256     float x_ist = vertex.x();
01257     float y_ist = vertex.y();
01258     
01259     float num_2 = DetectorData::Glast::xNum/2.; 
01260     float x_twr_bnd = fmod((x_ist + s_parms.tower_width*num_2), s_parms.tower_width);
01261     x_twr_bnd = x_twr_bnd - s_parms.tower_width*.5;
01262     float y_twr_bnd = fmod((y_ist + s_parms.tower_width*num_2), s_parms.tower_width);
01263     y_twr_bnd = y_twr_bnd - s_parms.tower_width*.5;
01264     
01265     x_twr_bnd = fabs(x_twr_bnd);
01266     y_twr_bnd = fabs(y_twr_bnd);
01267     float twr_bnd   = (x_twr_bnd > y_twr_bnd) ? x_twr_bnd : y_twr_bnd;
01268     
01269     xborder = x_twr_bnd;
01270     yborder = y_twr_bnd;
01271     
01272     return twr_bnd;
01273 }
01274 
01275 //########################################################
01276 double TrackerRecon::TAna_activeDistance()
01277 //########################################################
01278 {  
01279     
01280     float activeDist = -20.;
01281 #if 0 //THB: This depends on simulation environment, functionality needs to be restored
01282     Point firstHit = _mGFgamma->getFirstHit();
01283     Ray prjRay(firstHit, -t0);
01284     Point x_prj;
01285     
01286     GlastMed *glast = GlastMed::instance();
01287     
01288     int istLayer = _mGFgamma->firstLayer();
01289     
01290     float firstProp = 0.;
01291     if (istLayer > 0) { //go to next gap up + espsilon
01292         firstProp = SiTracker::traySpacing()/fabs(t0.z());
01293         x_prj = prjRay.position(firstProp);
01294     }
01295     else {
01296         x_prj = firstHit;
01297         firstProp = 0.;
01298     }
01299     
01300     const Medium *med0 = glast->inside(x_prj);
01301     prjRay = Ray(x_prj, -t0);
01302     const Medium *detMed = 0;
01303     if(med0){
01304         firstProp = med0->distanceToLeave(prjRay, detMed, 100.);
01305         activeDist = -2. - firstProp;
01306     }
01307     
01308     Detector *det =  0;
01309     if(detMed) {
01310         med0 = detMed;
01311         x_prj = prjRay.position(firstProp);
01312         prjRay = Ray(x_prj, -t0);
01313         firstProp = med0->distanceToLeave(prjRay, detMed, 100.);
01314         activeDist = -4. - firstProp;
01315         if(detMed) det = detMed->detector();
01316         if(det) {
01317             if(!strcmp(det->nameOf(), "SiDetector")) {
01318                 x_prj = prjRay.position(firstProp);
01319                 activeDist = static_cast<const SiDetectorMed*>(det)->data().insideActiveArea(x_prj);
01320             }
01321         }
01322     }
01323 #endif    
01324     return activeDist;
01325 }
01326 
01327 //########################################################
01328 double TrackerRecon::TAna_extraHits(double& norma, double& istHitCount, double& OutHits,
01329                                     double& ShwHits1, double& ShwHits2)
01330                                     //########################################################
01331 {  
01332     
01333     double SumHits = 0.;
01334     norma = 1.;
01335     OutHits = 0.;
01336     ShwHits1 = 0.;
01337     ShwHits2 = 0.;
01338     
01339     //  Find number of hits around first hit: 5 sigma out
01340     int firstLayer = _mGFgamma->firstLayer();
01341     Point firstHit = _mGFgamma->vertex();
01342     int diffXY = _mGFgamma->getXpair()->firstLayer()-_mGFgamma->getYpair()->firstLayer();
01343     float dz    =  _mGFgamma->getBest(SiData::X)->vertex().z() - 
01344         _mGFgamma->getBest(SiData::Y)->vertex().z();
01345     
01346     float hitRadFact = fabs(t0.z()) + sqrt(1. - t0.z()*t0.z())/fabs(t0.z());
01347     if(hitRadFact > 3.) hitRadFact = 3.;
01348     int ipln = parms->num_convs - firstLayer; 
01349     float radLenEff = (DetectorData::SiTracker::convRadLen(ipln) + 2.*parms->si_thickness/9.36 +.003)/fabs(t1.z());
01350     float thetaCone = .014/(m_CsICorrEnergy/2.)*sqrt(radLenEff)*(1.+.038*log(radLenEff));
01351     float minSprd  = 5.* thetaCone * parms->conv_gap; // 5 sigma cut
01352     float dltSprd  = minSprd;
01353     float norm = sqrt(t0.x()*t0.x() + t0.y()*t0.y());
01354     float xFact = 1., yFact = 1.;
01355     if(norm > 10000.*FLT_MIN) {
01356         xFact = 1. + (hitRadFact - 1.)*fabs(t0.x())/norm;
01357         yFact = 1. + (hitRadFact - 1.)*fabs(t0.y())/norm;
01358     }
01359     float dltX = dltSprd*xFact;
01360     float dltY = dltSprd*yFact;
01361     
01362     // Compute the First_hit_count variable
01363     istHitCount = _mclsData->numberOfHitsNear(firstLayer, dltX, dltY, firstHit);
01364     // separate the special case of 3 into 3 or 2.5
01365     if(istHitCount == 3 && diffXY == 0) { // Check if extra hits on the far side of the first gap
01366         SiData::Axis far_axis = SiData::X;
01367         double dR = dltX;
01368         if (dz>0) {
01369             far_axis = SiData::Y;
01370             dR = dltY;
01371         }
01372         int ihit_second = _mclsData->numberOfHitsNear(far_axis, firstLayer, dltX, firstHit);
01373         if (ihit_second == 2) istHitCount -=.5;
01374     }
01375     if(istHitCount == 1 && diffXY == 0) { // Check if extra hits on the far side of the first gap
01376         SiData::Axis far_axis = SiData::X;
01377         double dR = dltX;
01378         if (dz>0) {
01379             far_axis = SiData::Y;
01380             dR = dltY;
01381         }
01382         int ihit_second = _mclsData->numberOfHitsNear(far_axis, firstLayer, dltX, firstHit);
01383         if (ihit_second == 1) istHitCount -=.5;
01384     }
01385     
01386     //  Find the number of hits around the rest of the gamma trajectory
01387     float deltaS = parms->conv_gap/fabs(t0.z());
01388     double disp =  deltaS;
01389     int lastLayer = (int)(4+2.*log(m_CsICorrEnergy/.01) + firstLayer);
01390     if(lastLayer > parms->num_convs) lastLayer = parms->num_convs;
01391     
01392     float sumHits = _mclsData->numberOfHitsNear(firstLayer, .5*dltX, .5*dltY, firstHit);
01393     float shwHits1 = sumHits;
01394     float shwHits2 = 0; 
01395     if(m_firstLayer > 11) {
01396         shwHits1 = 0; 
01397         shwHits2 = sumHits;
01398     }
01399     
01400     if(sumHits < 2.) sumHits = 2.;
01401     if(lastLayer - firstLayer < 5 && lastLayer == parms->num_convs) sumHits +=.5;
01402     float outHits = 0;
01403     
01404     xFact *= sqrt(t0.z() *t0.z() + t0.x()*t0.x());
01405     yFact *= sqrt(t0.z() *t0.z() + t0.y()*t0.y());
01406     
01407     int i;
01408     for(i=firstLayer+1; i<parms->num_convs; i++) {
01409         ipln = parms->num_convs - i;
01410         radLenEff +=  (DetectorData::SiTracker::convRadLen(ipln) + 2.*parms->si_thickness/9.36 +.003)/fabs(t1.z());
01411         float thetaMS = .014/(m_CsICorrEnergy/2.)*sqrt(radLenEff)*(1.+.038*log(radLenEff));
01412         float s_total = (i-firstLayer) * deltaS;
01413         float xSprd = thetaMS * s_total * xFact * 2.021; // = 3.5 sigma/sqrt(3)
01414         float ySprd = thetaMS * s_total * yFact * 2.021;
01415         Point trkHit((Point)(disp*t0 + x0));
01416         if (xSprd > 50) xSprd = 50.;
01417         if (ySprd > 50) ySprd = 50.;
01418         float nearHits = _mclsData->numberOfHitsNear(i, xSprd, ySprd, trkHit);
01419         if(i< 12) shwHits1 +=  nearHits;
01420         else      shwHits2 +=  nearHits; 
01421         if( i < lastLayer) {
01422             sumHits +=  nearHits;
01423             outHits +=  _mclsData->numberOfHitsNear(i, 50.,   50.,   trkHit) - nearHits;
01424         }
01425         disp += deltaS;
01426     }
01427     
01428     SumHits = sumHits;
01429     norma = lastLayer - firstLayer;
01430     OutHits = outHits;
01431     ShwHits1 = shwHits1;
01432     ShwHits2 = shwHits2;
01433     return sumHits;
01434 }
01435 
01436 //########################################################
01437 double TrackerRecon::TAna_corrEnergy(double ShwHits1, double ShwHits2, double twr_bnd)
01438 //########################################################
01439 { 
01440     double eneCorr = 0;
01441     GFtrack* _Xbest = _mGFgamma->getXpair()->getBest();
01442     GFtrack* _Ybest = _mGFgamma->getYpair()->getBest();
01443     float hit_energy = 0.0003*ShwHits1  + .0013*ShwHits2;  //Energy in Hits
01444     float num_Layers_Crossed = _Xbest->numDataPoints()+ _Xbest->numGaps();
01445     if(_Xbest->numDataPoints() < _Ybest->numDataPoints()) 
01446         num_Layers_Crossed = _Ybest->numDataPoints()+ _Ybest->numGaps();
01447     float x_ing_energy = .0016*num_Layers_Crossed; // Take out observed layer correlation
01448     float edg_corr   =  (twr_bnd < 10.) ? 1 : .68 + (.069  - .0036* twr_bnd )*twr_bnd; // Edge of Tower correction 
01449     float trk_energy = hit_energy + x_ing_energy;  // Total Tracker energy  
01450     trk_energy /= (fabs(t0.z()) > .2) ? fabs(t0.z()) : .2; // Note: t0.z < 0
01451     eneCorr = (m_CsIEnergy + trk_energy)/edg_corr;
01452     return eneCorr;    
01453 }
01454 /*
01455 //########################################################
01456 void TrackerRecon::KalPrivateTup()
01457 //########################################################
01458 {
01459 
01460   int iwrite=0; 
01461   // Planes Tuple - Information of the XBest planes
01462   if (xtrackList.size() >0) {
01463                 GlastFit* _xtrack=_mbestXFit;
01464                 std::string title("kalplanes.tup");
01465                 for (int iplane=0; iplane<_xtrack->kplanelist.size(); iplane++){
01466                 kalplane_event==0 && iplane ==0? iwrite=1: iwrite=0; 
01467                 KalTup planetup(kalplane_event, iplane, *_xtrack);
01468                 planetup.output(iwrite,title);
01469                 }
01470                 kalplane_event++;
01471                 }
01472                 
01473                   // Tracks tuple
01474                   if (xtrackList.size() >0 && ytrackList.size() >0 ) {
01475                   std::string title_e("kalevent.tup");
01476                   kaltrack_event==0? iwrite=1: iwrite=0;
01477                   KalTup eventtup(kaltrack_event, xtrackList[0], ytrackList[0]);
01478                   eventtup.output(iwrite, title_e);
01479                   kaltrack_event++;
01480                   } 
01481 } */
01482 //--------------------------------------------------------
01483 //     Correction of the Energy
01484 //--------------------------------------------------------
01485 //########################################################
01486 double TrackerRecon::corrEnergy(int level, enum configuration, int nShowerHits, double slope)
01487 //########################################################
01488 {   
01489     // B. Atwood, A. Djannati, JA Hernando.
01490     
01491     // level for the Ecorrection
01492     //          1 - total number of hits in the tracker
01493     //          2 - number of hits in the gamma shower
01494     //          3 - and correction for the geometry leakeages
01495     
01496     double deltaE = 0.;
01497     
01498     if (level == 1) {
01499         // this correction is Hardwire for the baseline 4x4 and 5x10^-5 occupancy
01500         //  JA hernando, D. Melton 6/30/99
01501         // deltaE = 0.0004*(nShowerHits - 55);
01502         // previous code by Bill Atwood (5x5 but not relevant changes are expected
01503         deltaE = 0.0006 * (m_totalHits - 55);
01504         deltaE = 0.025 + 0.0008 * (m_totalHits - 55);
01505     } else if (level == 2) {
01506     } else {
01507     }
01508     
01509     return deltaE;
01510 }
01511 
01512 
01513 GFgamma*    TrackerRecon::gammaFit ()
01514 {
01515     return _mGFgamma;
01516 }

Generated at Wed Nov 21 12:20:45 2001 by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000