00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "reconstruction/TrackerRecon.h"
00016 #include "reconstruction/GlastRecon.h"
00017
00018
00019
00020
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
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
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 static bool CONTROL_writeOut = false;
00069 static int CONTROL_debug = 2;
00070 static double CONTROL_sigmaCut = 8.;
00071
00072
00073 static double CONTROL_minEnergy = 0.03;
00074
00075
00076
00077 static double XENE = 0.6;
00078 static unsigned int MAX_CANDIDATES = 4;
00079
00080
00081
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.;
00090 static double CONTROL_FEneGamma = 1.;
00091 static double CONTROL_FEneParticle = 1./3.;
00092
00093
00094
00095
00096 inline static double sqr(double x){return x*x;}
00097
00098 using namespace std;
00099
00100
00101 TrackerRecon::Parameters TrackerRecon::s_parms;
00102
00103
00104 namespace {
00105 const TrackerRecon::Parameters* parms = &TrackerRecon::params();
00106
00107 };
00108
00109
00110
00111
00112
00113 void TrackerRecon::Parameters::initialize ()
00114 {
00115
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
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
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
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
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
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
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
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
00221 i_FitSide_nXused = data.addElement("FitSide_nXused");
00222 i_FitSide_nYused = data.addElement("FitSide_nYused");
00223
00224
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
00237
00238
00239
00240
00241
00242 if(m_activeDist!=0) {
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
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
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
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
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
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
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
00375
00376
00377 void TrackerRecon::iniTrackerRecon()
00378
00379 {
00380
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
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
00430 _mclsData->loadFrom(*stripData);
00431
00432 data.addData(i_Conv_Layer_Hits, m_totalHits);
00433
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
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
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
00489
00490
00491
00492 m_Ecorr->setCsIEnergy (m_CsICorrEnergy);
00493
00494
00495
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
00505
00506 }
00507
00508
00509
00510
00511
00512
00513 void TrackerRecon::RCreconstruct(const SiData* stripData)
00514
00515 {
00516
00517
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
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
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
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 }
00597 }
00598
00599 if (OK) return OK;
00600
00601
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 }
00617 }
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 }
00632 }
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
00657
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
00723
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
00746
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;
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
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
00833 int naccepted = 0;
00834 bool ok = false;
00835
00836 if (ilayer >= DetectorData::SiTracker::numTrays()-3) return ok;
00837
00838
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
00849
00850
00851 for ( ; ihit<nhitsInLayer; ihit++) {
00852
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
00863
00864 PRef = createPRef(axis, ilayer, PIni);
00865
00866
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);
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
00940
00941
00942 void TrackerRecon::loadTuple(const SiData* _stripData)
00943
00944 {
00945
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
00963
00964
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
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
01007
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
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
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
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
01071
01072
01073
01074
01075
01076 if(cal == 0){
01077 return;
01078 }
01079 m_tkrVeto->compute();
01080
01081
01082 m_twrBounds->compute();
01083
01084
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
01094 m_extraHits->compute();
01095
01096
01097 m_Ecorr->compute();
01098
01099
01100 m_CsICorrEnergy = m_Ecorr->result()->energyCorr();
01101
01102
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
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
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
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
01180
01181
01182 int firstLayer = _mGFgamma->firstLayer();
01183 Point firstHit = _mGFgamma->vertex();
01184
01185
01186
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
01193
01194
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
01202
01203
01204 float deltaS = parms->conv_gap/fabs(t0.z());
01205
01206
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;
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
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
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) {
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
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;
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
01363 istHitCount = _mclsData->numberOfHitsNear(firstLayer, dltX, dltY, firstHit);
01364
01365 if(istHitCount == 3 && diffXY == 0) {
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) {
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
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;
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;
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;
01448 float edg_corr = (twr_bnd < 10.) ? 1 : .68 + (.069 - .0036* twr_bnd )*twr_bnd;
01449 float trk_energy = hit_energy + x_ing_energy;
01450 trk_energy /= (fabs(t0.z()) > .2) ? fabs(t0.z()) : .2;
01451 eneCorr = (m_CsIEnergy + trk_energy)/edg_corr;
01452 return eneCorr;
01453 }
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486 double TrackerRecon::corrEnergy(int level, enum configuration, int nShowerHits, double slope)
01487
01488 {
01489
01490
01491
01492
01493
01494
01495
01496 double deltaE = 0.;
01497
01498 if (level == 1) {
01499
01500
01501
01502
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 }