00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
#include "StRichPIDMaker.h"
00233
00234
#include <map>
00235
#include <algorithm>
00236
#ifndef ST_NO_NAMESPACES
00237
using std::min;
00238
using std::max;
00239
using std::map;
00240
using std::pair;
00241
using std::make_pair;
00242
using std::less;
00243
00244
00245
#endif
00246
00247
00248
#include "StRichDisplayActivate.h"
00249
#include "StRichTrackingControl.h"
00250
#include "StRichMcSwitch.h"
00251
00252
#define myrICH_WITH_NTUPLE 1
00253
00254
00255
00256
#include "St_DataSet.h"
00257
#include "St_DataSetIter.h"
00258
#include "StMessMgr.h"
00259
00260
00261
#include "TH1.h"
00262
#include "TH3.h"
00263
#include "TNtuple.h"
00264
#include "Stiostream.h"
00265
#include <math.h>
00266
#include <float.h>
00267
#ifdef SUN
00268
#include <ieeefp.h>
00269
#endif
00270
00271
00272
00273
#ifdef RICH_WITH_PAD_MONITOR
00274
#include "StRichDisplayMaker/StRichDrawableTTrack.h"
00275
#include "StRichDisplayMaker/StRichDrawableTRings.h"
00276
#include "StRichDisplayMaker/StRichPadMonitor.h"
00277
#endif
00278
00279
#ifdef RICH_WITH_L3_TRACKS
00280
#include "StDaqLib/GENERIC/EventReader.hh"
00281
#include "StDaqLib/L3/L3_Reader.hh"
00282
#include "StDaqLib/TPC/trans_table.hh"
00283
#include "StDAQMaker/StDAQReader.h"
00284
#endif
00285
00286
00287
00288
#include "StGlobals.hh"
00289
#include "StParticleTypes.hh"
00290
#include "StParticleDefinition.hh"
00291
#include "StThreeVectorF.hh"
00292
#include "StPhysicalHelixD.hh"
00293
#include "StMemoryInfo.hh"
00294
#include "SystemOfUnits.h"
00295
#include "PhysicalConstants.h"
00296
00297
00298
#include "StEventTypes.h"
00299
#include "StRichPid.h"
00300
#include "StRichPhotonInfo.h"
00301
#include "StRichPidTraits.h"
00302
#include "StTpcDedxPidAlgorithm.h"
00303
00304
#include "StEventMaker/StRootEventManager.hh"
00305
00306
00307
#include "StRrsMaker/StRichGeometryDb.h"
00308
#include "StRrsMaker/StRichCoordinateTransform.h"
00309
#include "StRrsMaker/StRichEnumeratedTypes.h"
00310
#include "StRchMaker/StRichSimpleHitCollection.h"
00311
00312
00313
#include "StRichRingCalculator.h"
00314
#include "StRichRingDefinition.h"
00315
#include "StRichTrack.h"
00316
#include "StRichMCTrack.h"
00317
00318
#ifdef myRICH_WITH_MC
00319
00320
#include "StMcEventTypes.hh"
00321
#include "StMcEvent.hh"
00322
00323
00324
#include "StAssociationMaker/StAssociationMaker.h"
00325
#include "StAssociationMaker/StTrackPairInfo.hh"
00326
00327
00328
#include "tables/St_g2t_track_Table.h"
00329
#endif
00330
00331
00332
00333
#include "TObject.h"
00334
#include "TClonesArray.h"
00335
00336
#ifdef myPrivateVersion
00337
#include "TreeEntryClasses.h"
00338
#endif
00339
00340
00341
00342
00343
00344
00345
static const char rcsid[] =
"$Id: StRichPIDMaker.cxx,v 2.56 2007/04/28 17:56:50 perev Exp $";
00346
00347 StRichPIDMaker::StRichPIDMaker(
const Char_t *name,
bool writeNtuple) :
StMaker(name) {
00348 drawinit = kFALSE;
00349 fileName = 0;
00350 kWriteNtuple=writeNtuple;
00351
00352 mTotalEvents = 0;
00353 mGoodEvents = 0;
00354
00355
00356
00357 mProductionVersion = -999;
00358
00359
00360
00361
00362
00363 this->initCutParameters();
00364
00365 }
00366
00367 StRichPIDMaker::~StRichPIDMaker() {}
00368
00369
void StRichPIDMaker::initCutParameters() {
00370
00371
00372
00373 mVertexWindow = 200.*centimeter;
00374
00375
00376
00377
00378
00379 mPtCut = 0.5*GeV;
00380 mEtaCut = 0.5;
00381 mLastHitCut = 100.0*centimeter;
00382 mDcaCut = 3.0*centimeter;
00383 mFitPointsCut = 20;
00384 mPathCut = 500*centimeter;
00385 mPadPlaneCut = 1.0*centimeter;
00386 mRadiatorCut = 1.0*centimeter;
00387
00388 mThresholdMomentum = 0.5*GeV;
00389
00390
00391
00392
00393 mPrecision = 100*micrometer;
00394
00395 }
00396
00397 Int_t StRichPIDMaker::Init() {
00398
00399
00400
00401
00402 pion = StPionMinus::instance();
00403 kaon = StKaonMinus::instance();
00404 proton = StAntiProton::instance();
00405
00406 mListOfParticles.clear();
00407 mListOfParticles.resize(3);
00408 mListOfParticles[0] = pion;
00409 mListOfParticles[1] = kaon;
00410 mListOfParticles[2] = proton;
00411
00412
00413
00414
00415 cout <<
"StRichPIDMaker::init() trajectory correction turned on." << endl;
00416 mTrackRefit =
true;
00417
00418
00419
00420
00421
00422 mMaterialDb = StRichMaterialsDb::getDb();
00423 mGeometryDb = StRichGeometryDb::getDb();
00424 mCoordinateTransformation = StRichCoordinateTransform::getTransform(mGeometryDb);
00425 mMomentumTransformation = StRichMomentumTransform::getTransform(mGeometryDb);
00426
00427
00428
00429
00430 mPadMonitor = 0;
00431
00432
00433
00434
00435 mDoGapCorrection =
true;
00436
00437
00438
00439
00440
00441
00442
00443 mDefaultShortWave = 174.633e-7;
00444 mDefaultLongWave = 217.039e-7;
00445
00446
if ( (mDefaultShortWave != mShortWave) &&
00447 (mDefaultLongWave != mLongWave) ) {
00448 mMaterialDb->setWavelengthRange(mDefaultShortWave,mDefaultLongWave);
00449 }
00450
00451 mPadPlaneDimension = mGeometryDb->padPlaneDimension();
00452 mRadiatorDimension = mGeometryDb->radiatorDimension();
00453
00454
00455
00456
00457 this->printCutParameters();
00458 this->initNtuples();
00459
00460
return StMaker::Init();
00461 }
00462
00463
00464
void StRichPIDMaker::Clear(Option_t *opt) {
00465
StMaker::Clear();
00466 }
00467
00468
00469 Int_t StRichPIDMaker::Make() {
00470
00471 cout <<
"StRichPIDMaker::Make() production= ";
00472 cout << this->productionVersion() << endl;
00473
00474 mPrintThisEvent =
false;
00475 mNumberOfRingHits=0;
00476 mTotalEvents++;
00477
00478
00479
#ifdef myRICH_WITH_MC
00480
00481 mEvent = 0;
00482 mEvent = ((
StMcEvent*) GetDataSet(
"StMcEvent");
00483
if (!mEvent) {
00484 cout <<
"StRichPIDMaker:Make() ---> No StMcEvent! Return kStWarn." << endl;
00485
return kStWarn;
00486 }
00487
#endif
00488
00489
00490
00491
00492
00493
StEvent* rEvent;
00494 rEvent = (
StEvent *) GetInputDS(
"StEvent");
00495
00496
00497
00498
00499
00500
00501
bool goodRichEvent = this->checkEvent(rEvent);
00502
00503
if (!rEvent) {
00504 cout <<
"StRichPIDMaker::Make()\n";
00505 cout <<
"\tWarning: No StEvent" << endl;
00506
return kStWarn;
00507 }
00508
if (!rEvent->
primaryVertex()) {
00509 cout <<
"StRichPIDMaker::Make()\n";
00510 cout <<
"\tWarning: No vertex" << endl;
00511
return kStWarn;
00512 }
00513
00514
00515
if (goodRichEvent) {
00516 mGoodEvents++;
00517 }
00518
00519
00520
00521
00522
00523 mRichTracks = 0;
00524 mNumberOfPrimaries = 0;
00525 mNegativePrimaries = 0;
00526
00527
00528
00529
00530
00531
const StSPtrVecRichHit* pRichHits = 0;
00532
const StSPtrVecRichCluster* pRichClusters = 0;
00533
const StSPtrVecRichPixel* pRichPixels = 0;
00534
00535
int myRichHits = 0;
00536
int myRichPixels = 0;
00537
00538
StRichCollection* richCollection=0;
00539
00540
if (goodRichEvent) {
00541 richCollection = rEvent->
richCollection();
00542 mRichCollection = richCollection;
00543
if (richCollection) {
00544
if (richCollection->pixelsPresent()) {
00545 myRichPixels = richCollection->
getRichPixels().size();
00546
const StSPtrVecRichPixel& richPixels =
00547 richCollection->getRichPixels();
00548 pRichPixels = &richPixels;
00549 }
00550
00551
if (richCollection->clustersPresent()) {
00552
const StSPtrVecRichCluster& richClusters =
00553 richCollection->getRichClusters();
00554 pRichClusters = &richClusters;
00555 }
00556
00557
if (richCollection->hitsPresent()) {
00558
const StSPtrVecRichHit& richHits =
00559 richCollection->getRichHits();
00560 pRichHits = &richHits;
00561
if(pRichHits)
00562 myRichHits = pRichHits->size();
00563 }
00564
00565
00566
00567
if (pRichHits) {
00568
00569 mNumberOfPrimaries = this->fillTrackList(rEvent,pRichHits);
00570 mRichTracks = mListOfStRichTracks.size();
00571 }
00572
else {
00573 cout <<
"\trichCollection but no Hits: clearing richtracklist" << endl;
00574 this->clearTrackList();
00575 }
00576
00577 }
00578
else {
00579 cout <<
"\tNo richCollection: clearing richtracklist" << endl;
00580 this->clearTrackList();
00581 }
00582 }
00583
else {
00584 this->clearTrackList();
00585 }
00586
00587
00588
00589
00590
00591
00592
00593
00594 size_t ii;
00595
00596
if(!rEvent->
tpcHitCollection()) {
00597
00598
00599
00600
StTpcHitCollection* theTpcHitCollection =
new StTpcHitCollection();
00601 rEvent->
setTpcHitCollection(theTpcHitCollection);
00602
00603
00604 StRootEventManager* theEvtManager =
new StRootEventManager();
00605 theEvtManager->setMaker(
this);
00606
00607
00608
int status = theEvtManager->openEvent(
"dst");
00609
if(status == oocError) {
00610 cout <<
"StRichPIDMaker::Make()\n";
00611 cout <<
"\tWARNING:\n";
00612 cout <<
"\tCannot Open dataset \"dst\"";
00613 cout <<
"\tCannot make the StTpcHitCollection\n" << endl;
00614 }
00615
else {
00616
long nrows;
00617 dst_point_st* dstPoints = theEvtManager->returnTable_dst_point(nrows);
00618
00619
if(!dstPoints) {
00620 cout <<
"StRichPIDMaker::Make()\n";
00621 cout <<
"\tWARNING: Cannot get the dstPoints\n";
00622 cout <<
"\tContinuing..." << endl;
00623 }
00624
else {
00625
00626
00627
#ifndef ST_NO_TEMPLATE_DEF_ARGS
00628
typedef map < unsigned short, StTrack*> trackKeyToTrackMapType;
00629
#else
00630
typedef map < unsigned short, StTrack*, less<unsigned short>, allocator < OS_PAIR<unsigned short, StTrack* > > trackKeyToTrackMapType;
00631
#endif
00632
trackKeyToTrackMapType trackKeyToTrack;
00633
00634
if (goodRichEvent) {
00635
00636
for (ii=0; ii<mListOfStRichTracks.size(); ++ii) {
00637
StTrackNode* theTrackNode = mListOfStRichTracks[ii]->getStTrack()->node();
00638
for (size_t jj=0; jj<theTrackNode->
entries(); ++jj) {
00639
00640
StTrack* currentTrack = theTrackNode->
track(jj);
00641
if (currentTrack->
bad())
continue;
00642
00643
if(!currentTrack->
detectorInfo()) {
00644 cout <<
"StRichPIDMaker::Make()\n";
00645 cout <<
"\tWARNING: No detectorInfo()\n";
00646 cout <<
"\tassocciated with the track. Continuing..." << endl;
00647
continue;
00648 }
00649 trackKeyToTrack.insert(make_pair(currentTrack->
key(),currentTrack));
00650
00651
break;
00652 }
00653 }
00654 }
00655
00656
00657 StSPtrVecTrackNode& theNodes = rEvent->
trackNodes();
00658
for (size_t nodeIndex = 0; nodeIndex<theNodes.size(); ++nodeIndex) {
00659
StTrackNode* theTrackNode = theNodes[nodeIndex];
00660
00661
for (size_t globalIndex=0; globalIndex<theTrackNode->
entries();++globalIndex) {
00662
StTrack* currentTrack = theTrackNode->
track(globalIndex);
00663
if (currentTrack->
bad())
continue;
00664
00665
if (currentTrack->
geometry()->
momentum().perp()>=1.5
00666 &&
00667 fabs(currentTrack->
geometry()->
momentum().pseudoRapidity())<1.
00668 &&
00669 currentTrack->
flag()>=0) {
00670
if(!currentTrack->
detectorInfo()) {
00671 cout <<
"StRichPIDMaker::Make()\n";
00672 cout <<
"\tWARNING: No detectorInfo()\n";
00673 cout <<
"\tassocciated with the track. Continuing..." << endl;
00674
continue;
00675 }
00676 trackKeyToTrack.insert(make_pair(currentTrack->
key(),currentTrack));
00677
00678
break;
00679 }
00680 }
00681 }
00682
00683 cout <<
"StRichPIDMaker::Make(): Adding hits to " << trackKeyToTrack.size() <<
" tracks" << endl;
00684 cout <<
"\t " << mListOfStRichTracks.size() <<
" Rich Tracks " << endl;
00685
00686
00687
00688
00689
for(trackKeyToTrackMapType::const_iterator titer= trackKeyToTrack.begin();
00690 titer!=trackKeyToTrack.end(); ++titer) {
00691
00692
StTrack* currentTrack = (*titer).second;
00693
if (currentTrack->
bad())
continue;
00694
00695
if(!currentTrack->
detectorInfo()) {
00696 cout <<
"StRichPIDMaker::Make()\n";
00697 cout <<
"\tWARNING: No detectorInfo()\n";
00698 cout <<
"\tassocciated with the track. Continuing..." << endl;
00699
continue;
00700 }
00701
00702
unsigned short trackKey = currentTrack->
key();
00703
for(
int i=0; i<nrows; i++) {
00704
if(dstPoints[i].id_track != trackKey)
continue;
00705
StTpcHit* tpcHit =
new StTpcHit(dstPoints[i]);
00706
00707
00708
00709
00710
00711
00712
00713
00714
if(theTpcHitCollection->
addHit(tpcHit)) {
00715 currentTrack->
detectorInfo()->
addHit(tpcHit);
00716 }
00717
00718 }
00719 }
00720
delete theEvtManager;
00721 theEvtManager=0;
00722 }
00723 }
00724 }
00725
00726
00727
00728
00729
00730
00731
00732
if (!goodRichEvent)
return kStWarn;
00733
if (!richCollection) {
00734 cout <<
"StRichPIDMaker::Make()\n";
00735 cout <<
"\tWARNING: Cannot get richCollection from StEvent\n";
00736 cout <<
"\tSkip Event" << endl;
00737
return kStWarn;
00738 }
00739
00740
00741
00742
00743
00744
00745
00746
#ifdef RICH_WITH_PAD_MONITOR
00747
00748
00749
00750
00751
00752 mPadMonitor=StRichPadMonitor::getInstance(mGeometryDb);
00753 mPadMonitor->clearMisc();
00754
#endif
00755
00756
00757 StPtrVecHit tpcHits;
00758 StRichRingCalculator* ringCalc;
00759
00760
for (ii=0; ii<mListOfStRichTracks.size(); ii++) {
00761
00762 StRichTrack* richTrack = mListOfStRichTracks[ii];
00763
00764
if (mTrackRefit) richTrack->correctTrajectory();
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774 StThreeVectorF refitResidual(-999.,-999.,-999.);
00775
00776
if(richTrack->getAssociatedMIP()) {
00777 refitResidual = richTrack->getProjectedMIP() - richTrack->getAssociatedMIP()->local();
00778 }
00779 richTrack->getPidTrait()->setRefitResidual(refitResidual);
00780
00781
if(richTrack->getStTrack()->detectorInfo())
00782 tpcHits = richTrack->getStTrack()->detectorInfo()->hits(kTpcId);
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
for (size_t iParticle=0; iParticle<mListOfParticles.size(); iParticle++) {
00800
00801
00802
00803
00804
00805
if ( richTrack->fastEnough(mListOfParticles[iParticle]) &&
00806 richTrack->isGood(mListOfParticles[iParticle]) ) {
00807
00808 ringCalc =
new StRichRingCalculator(richTrack,mListOfParticles[iParticle]);
00809
00810
00811
00812
00813
00814
00815
00816 ringCalc->calculateArea();
00817
00818
00819
00820
00821
00822 this->hitFilter(pRichHits,ringCalc);
00823
00824
00825
00826
00827
00828
00829 this->fillPIDTraits(ringCalc);
00830
00831
delete ringCalc;
00832 ringCalc = 0;
00833 }
00834
00835 }
00836
00837 }
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
for (ii=0; ii<mListOfStRichTracks.size(); ii++) {
00854
00855 StRichTrack* richTrack = mListOfStRichTracks[ii];
00856
00857
StRichPidTraits* theTraits = richTrack->getPidTrait();
00858
00859
if(!theTraits) {
00860 cout <<
"StRichPIDMaker::Make()\n";
00861 cout <<
"\tERROR Processing the PIDTraits\n";
00862 cout <<
"\tContinuing..." << endl;
00863
continue;
00864 }
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
StTrack* track = richTrack->getStTrack();
00882
if (track && !track->bad()) {
00883
00884
00885
00886
00887 track->addPidTraits(richTrack->getPidTrait());
00888
00889
00890
#ifdef myPrivateVersion
00891
00892
00893
00894 m_Track->addTrackInfo(richTrack,rEvent,mMaterialDb,
00895 mListOfStRichTracks.size(),mNegativePrimaries);
00896
00897
00898 vector<StRichRingHit*> piHits = richTrack->getRingHits(pion);
00899
for (
int i=0;i<piHits.size();i++) {
00900 HitEntry tempHit(piHits[i]->getHit()->local().x(),piHits[i]->getHit()->local().y(),
00901 piHits[i]->getDist(), piHits[i]->getNSigma(),
00902 piHits[i]->getAngle()/degree,
00903 pion->pdgEncoding(),piHits[i]->getHit()->charge(),
00904 (*pRichClusters)[piHits[i]->getHit()->clusterNumber()]->numberOfPads(),
00905 piHits.size());
00906 m_Track->addHit(tempHit);
00907 }
00908
00909
00910 vector<StRichRingHit*> kaHits = richTrack->getRingHits(kaon);
00911
for (
int i=0;i<kaHits.size();i++) {
00912 HitEntry tempHit(kaHits[i]->getHit()->local().x(),kaHits[i]->getHit()->local().y(),
00913 kaHits[i]->getDist(), kaHits[i]->getNSigma(),
00914 kaHits[i]->getAngle()/degree,
00915 kaon->pdgEncoding(),kaHits[i]->getHit()->charge(),
00916 (*pRichClusters)[kaHits[i]->getHit()->clusterNumber()]->numberOfPads(),
00917 kaHits.size());
00918 m_Track->addHit(tempHit);
00919 }
00920
00921
00922
00923 vector<StRichRingHit*> prHits = richTrack->getRingHits(proton);
00924
for (
int i=0;i<prHits.size();i++) {
00925 HitEntry tempHit(prHits[i]->getHit()->local().x(),prHits[i]->getHit()->local().y(),
00926 prHits[i]->getDist(), prHits[i]->getNSigma(),
00927 prHits[i]->getAngle()/degree,
00928 proton->pdgEncoding(),prHits[i]->getHit()->charge(),
00929 (*pRichClusters)[prHits[i]->getHit()->clusterNumber()]->numberOfPads(),
00930 prHits.size());
00931 m_Track->addHit(tempHit);
00932 }
00933
00934 myTree->Fill();
00935 m_Track->clear();
00936
#endif
00937
}
00938
00939
else {
00940 cout <<
"StRichPIDMaker::Make()\n";
00941 cout <<
"\tCannot fill the PidTrait to the StTrack" << endl;
00942 cout <<
"\tContinuing..." << endl;
00943 }
00944 richTrack = 0;
00945 }
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
#ifdef RICH_WITH_PAD_MONITOR
00957
this->drawPadPlane(rEvent,mPrintThisEvent);
00958
#endif
00959
00960 this->fillRichSoftwareMonitor(rEvent);
00961
00962
00963
#ifdef myRICH_WITH_MC
00964
if (kWriteNtuple) this->fillMcTrackNtuple(pRichClusters);
00965
if (kWriteNtuple) this->fillMcPixelNtuple(pRichPixels);
00966
if (kWriteNtuple) this->fillMcPhotonNtuple(mEvent,pRichClusters,pRichHits);
00967
if (kWriteNtuple) this->fillGeantHitNtuple();
00968
#endif
00969
00970
return kStOK;
00971 }
00972
00973
00974 Int_t StRichPIDMaker::Finish() {
00975
00976 cout <<
"StRichPIDMaker::Finish()" << endl;
00977 this->printCutParameters();
00978
00979
#ifdef myRICH_WITH_NTUPLE
00980
if(file) {
00981 cout <<
"StRichPIDMaker::Finish() writing file ...." << endl;
00982 file->Write();
00983 file->Close();
00984
delete file;
00985 file = 0;
00986 cout <<
"StRichPIDMaker::Finish() done writing file." << endl;
00987 }
00988
#endif
00989
00990 cout <<
"Total Number of Events = " << mTotalEvents << endl;
00991 cout <<
"Total Number of Events that passed cuts = " << mGoodEvents << endl;
00992
00993
return kStOK;
00994 }
00995
00996
void StRichPIDMaker::setTrackRefit(
bool refit) {mTrackRefit = refit;}
00997
00998
void StRichPIDMaker::clearTrackList() {
00999
01000
for (size_t trackIndex=0; trackIndex<mListOfStRichTracks.size(); trackIndex++) {
01001
delete mListOfStRichTracks[trackIndex];
01002 mListOfStRichTracks[trackIndex] = 0;
01003 }
01004 mListOfStRichTracks.clear();
01005 mListOfStRichTracks.resize(0);
01006 }
01007
01008 Int_t StRichPIDMaker::fillTrackList(
StEvent* tempEvent,
01009
const StSPtrVecRichHit* richHits) {
01010
01011 mNumberOf1GeV=0;
01012 this->clearTrackList();
01013
01014 mNumberOfPrimaries = tempEvent->
primaryVertex()->
numberOfDaughters();
01015
01016
for (
int ii=0; ii<mNumberOfPrimaries; ii++) {
01017
01018
StTrack* track = tempEvent->
primaryVertex()->
daughter(ii);
01019
01020
if (this->checkTrack(track)) {
01021
01022
#ifdef myRICH_WITH_MC
01023
StRichMCTrack* tempTrack =
new StRichMCTrack(track,mMagField);
01024 cout <<
"StRichPIDMaker::fillTrackList() --> creating StMcTrack!"
01025 << endl;
01026
#else
01027
StRichTrack* tempTrack =
new StRichTrack(track,mMagField);
01028
#endif
01029
01030
01031
01032
StTrack* theGlobalTrack = track->node()->track(global);
01033
01034
if(!theGlobalTrack->
bad() && this->checkTrack(tempTrack)) {
01035
01036
01037
01038
01039 tempTrack->assignMIP(richHits);
01040
01041
if (tempTrack->getMomentum().mag()>1)
01042 mNumberOf1GeV++;
01043
01044
01045
01046
01047
01048
01049
01050
01051
StRichPidTraits* theRichPidTraits =
new StRichPidTraits();
01052
01053
StRichHit* theAssociatedMip = 0;
01054 StThreeVectorD theMipResidual(-999.,-999.,-999.);
01055
01056
if (!tempTrack->getAssociatedMIP()) {
01057 cout <<
"StRichPIDMaker::fillTrackList()\n";
01058 cout <<
"\tWARNING Rich Track has no AssociatedMIP\n";
01059 cout <<
"\tp= "
01060 << tempTrack->getStTrack()->geometry()->momentum().mag()
01061 << endl;
01062 }
01063
else {
01064 theAssociatedMip = tempTrack->getAssociatedMIP();
01065 theMipResidual =
01066 tempTrack->getProjectedMIP() - theAssociatedMip->
local();
01067 }
01068
01069 theRichPidTraits->
setProductionVersion(mProductionVersion);
01070
01071 theRichPidTraits->
setAssociatedMip(theAssociatedMip);
01072 theRichPidTraits->
setMipResidual(theMipResidual);
01073
01074
double signed3dDca = -999.;
01075
double signed2dDca = -999.;
01076
01077
if(theGlobalTrack) {
01078 signed3dDca = this->calculateSignedDca(theGlobalTrack, &signed2dDca);
01079 }
01080
01081
01082
01083 theRichPidTraits->
setSignedDca2d(signed2dDca);
01084 theRichPidTraits->
setSignedDca3d(signed3dDca);
01085
01086 mRichCollection->addTrack(tempTrack->getStTrack());
01087
01088
01089
01090
01091
01092
01093
01094
01095 tempTrack->addPidTrait(theRichPidTraits);
01096
01097
01098
01099
01100 tempTrack->setMomentumLoss();
01101
01102 mListOfStRichTracks.push_back(tempTrack);
01103 }
01104
else {
01105
delete tempTrack;
01106 tempTrack=0;
01107 }
01108 }
01109
01110
if (tempEvent->
primaryVertex()->
daughter(ii)->
geometry()->
charge() < 0) {
01111 mNegativePrimaries++;
01112 }
01113 }
01114
01115
01116
01117
01118
#ifdef myRICH_WITH_MC
01119
if (!makeTrackAssociations(mEvent,richHits)) {
01120 cout <<
"can not make track associations. Return kStWarn! " << endl;
01121
return kStWarn;
01122 }
01123
#endif
01124
01125 cout <<
"StRichPIDMaker::trackList=" << mListOfStRichTracks.size() << endl;
01126
return mNumberOfPrimaries;
01127 }
01128
01129
01130 Float_t StRichPIDMaker::calculateSignedDca(
const StTrack* track,
double* dca2d) {
01131
01132
01133
01134
01135
01136
01137
01138
StHelixD aHelix = track->geometry()->helix();
01139
01140
double dca3d = aHelix.
distance(mVertexPos);
01141
01142
01143
01144
01145 StThreeVectorD circleCenter(aHelix.
xcenter(), aHelix.
ycenter(), 0.);
01146
01147 StThreeVectorD vertex2d(mVertexPos.x(), mVertexPos.y(), 0.);
01148
01149
double distanceToCircleCenterFromVertex =
01150 abs(circleCenter - vertex2d);
01151
01152 *dca2d =
01153 (1./aHelix.
curvature() - distanceToCircleCenterFromVertex);
01154
01155
double signOfDca = sign((*dca2d));
01156
01157
return (signOfDca * dca3d);
01158 }
01159
01160
void StRichPIDMaker::hitFilter(
const StSPtrVecRichHit* richHits,
01161 StRichRingCalculator* ringCalculator) {
01162
01163
01164
01165
01166
if(!richHits) {
01167 cout <<
"StRichPIDMaker::hitFilter()\n";
01168 cout <<
"\tERROR no hits..." << endl;
01169
return;
01170 }
01171
01172 StThreeVectorF pointOnRing;
01173 StRichTrack* currentTrack = ringCalculator->getRing(eInnerRing)->getTrack();
01174
01175
if(!currentTrack) {
01176 cout <<
"StRichPIDMaker::hitFilter()\n";
01177 cout <<
"\tERROR no track" << endl;
01178
return;
01179 }
01180
01181 StThreeVectorF trackMomentum = currentTrack->getMomentum();
01182
01183
if(!checkTrackMomentum(abs(trackMomentum)))
return;
01184
01185
StRichHit* centralHit = currentTrack->getAssociatedMIP();
01186
if(!centralHit) {
01187 cout <<
"StRichPIDMaker::hitFilter()\n";
01188 cout <<
"\tERROR no associated MIP" << endl;
01189
return;
01190 }
01191
01192
01193
01194
01195
01196
if( !centralHit->
isSet(eMip) ) {
01197 cout <<
"StRichPIDMaker::hitFilter()\n";
01198 cout <<
"\tWARNING!\n";
01199 cout <<
"\tCentral Hit is not classified as\n";
01200 cout <<
"\ta MIP q=(" << centralHit->
charge() <<
")\n";
01201 cout <<
"\tContinuing...for now..." << endl;
01202
01203 }
01204
01205 StThreeVectorF central = centralHit->
local();
01206
01207
01208
01209
01210
01211
01212 StThreeVectorF mipResidual =
01213 ( central - currentTrack->getProjectedMIP() );
01214
01215 StParticleDefinition* particle =
01216 ringCalculator->getRing(eInnerRing)->getParticleType();
01217
int particleType = particle->pdgEncoding();
01218
01219
01220
01221
01222
#ifdef RICH_WITH_PAD_MONITOR
01223
mPadMonitor->drawMarker(central);
01224
#endif
01225
01226
01227
01228
01229
01230
01231
int photonNumber=0;
01232
const int maxIterForInitialPsi = 40;
01233
const int maxIterForRingPsi = 50;
01234
01235 StSPtrVecRichHitConstIterator hitIter;
01236
for (hitIter = richHits->begin();
01237 hitIter != richHits->end(); hitIter++) {
01238
01239
if( (*hitIter) == centralHit)
continue;
01240
if ( !(*hitIter)->isSet(ePhotoElectron) )
continue;
01241
01242 ringCalculator->clear();
01243 StThreeVectorF hit = (*hitIter)->local();
01244
01245
01246
01247
01248
01249
if( hit.x()<-65 )
continue;
01250
01251
01252
01253
01254 innerDistance = ringCalculator->getInnerDistance(hit,innerAngle);
01255 outerDistance = ringCalculator->getOuterDistance(hit,outerAngle);
01256 meanDistance = ringCalculator->getMeanDistance(hit,meanAngle);
01257 ringWidth = ringCalculator->getRingWidth();
01258
double quartzPath = ringCalculator->getMeanPathInQuartz();
01259
double radPath = ringCalculator->getMeanPathInRadiator();
01260
01261
01262
01263
01264
01265
01266
01267 photonNumber++;
01268
01269
01270
01271
#ifdef RICH_WITH_PAD_MONITOR
01272
01273
#endif
01274
01275
01276
01277
01278
01279 StThreeVectorF referenceLine = (hit-central);
01280
if (referenceLine.mag()<1.e-10)
continue;
01281
01282
#ifdef RICH_WITH_PAD_MONITOR
01283
01284
#endif
01285
01286
01287
01288
01289
01290
01291
01292 ringCalculator->getRing(eInnerRing)->getPoint(innerAngle,pointOnRing);
01293
if(pointOnRing.x() == FLT_MAX) {
01294
01295
01296
01297
01298
continue;
01299 }
01300
01301
01302 StThreeVectorF ringPointLine = pointOnRing - central;
01303
01304
01305
double psi = innerAngle;
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
int signOfTheta =
01324 sign(ringPointLine.x()*referenceLine.y() - ringPointLine.y()*referenceLine.x());
01325
double sineTheta = abs( (ringPointLine.unit()).cross(referenceLine.unit()) );
01326
01327
01328
float minDistToRefLine =
01329 fabs(ringPointLine.mag())* sineTheta;
01330
01331
01332
01333 StThreeVectorF newPointOnRing;
01334
bool anotherIteration =
true;
01335
bool convergence =
false;
01336
01337
double step = 1.*degree;
01338
double maxChange = 5.*degree;
01339
01340
01341
01342
01343
01344
if(signOfTheta<0) step *= -1.;
01345
01346
01347
int ctr = 0;
01348
while (anotherIteration && ctr<maxIterForInitialPsi) {
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364 psi += step;
01365 ctr++;
01366
01367
01368 ringCalculator->getRing(eInnerRing)->getPoint(psi,newPointOnRing);
01369
01370
if(newPointOnRing.x() == FLT_MAX) {
01371
01372
01373 psi -= step;
01374 step *= 0.5;
01375
continue;
01376 }
01377
01378 ringPointLine = newPointOnRing - central;
01379
01380
int signOfNewTheta =
01381 sign(ringPointLine.x()*referenceLine.y() -
01382 ringPointLine.y()*referenceLine.x());
01383 sineTheta = abs( (ringPointLine.unit()).cross(referenceLine.unit()) );
01384
01385
01386
double newDistToRefLine =
01387 abs(ringPointLine)* sineTheta;
01388
01389
01390
01391
01392
if(ctr > maxIterForRingPsi)
01393 anotherIteration =
false;
01394
01395
if (newDistToRefLine<mPrecision) {
01396 convergence =
true;
01397
break;
01398 }
01399
01400
01401
01402
if( (signOfTheta != signOfNewTheta) ||
01403 ( (signOfTheta == signOfNewTheta) &&
01404 (newDistToRefLine > minDistToRefLine) ) ) {
01405
01406 signOfTheta = signOfNewTheta;
01407 step *= -0.5;
01408 }
01409
else {
01410
01411
01412 step = (step>0) ?
01413 min(maxChange,(step*1.2)) : max(-1.*maxChange,step*1.2);
01414
01415
if(newDistToRefLine < 3.*centimeter) {
01416
01417 step = (step>0) ?
01418 min(1.*degree,step) : max(-1.*degree,step);
01419 }
01420
01421 }
01422
01423
01424 minDistToRefLine = newDistToRefLine;
01425
01426 };
01427
01428
if(!convergence)
continue;
01429
01430
01431
01432
01433 StThreeVectorF innerRingPoint = newPointOnRing;
01434
01435
#ifdef RICH_WITH_PAD_MONITOR
01436
01437
#endif
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447 StThreeVectorF outerRingPoint;
01448
01449
int iterationNumber = 0;
01450
double littleStep = 1.*degree;
01451
double modifiedPsi = psi;
01452
if(modifiedPsi < 0) littleStep *= -1.;
01453
01454
while (iterationNumber<maxIterForInitialPsi) {
01455 iterationNumber++;
01456 ringCalculator->getRing(eOuterRing)->getPoint(modifiedPsi,outerRingPoint);
01457
01458
01459
if ( (outerRingPoint.x() == FLT_MAX) ||
01460 (
01461 fabs(outerRingPoint.x()) > mGeometryDb->padPlaneDimension().x() ||
01462 fabs(outerRingPoint.y()) > mGeometryDb->padPlaneDimension().y()
01463 )
01464 ) {
01465
01466
01467 modifiedPsi+=littleStep;
01468 }
01469
else {
01470
01471
break;
01472 }
01473 }
01474
01475
01476 psi = modifiedPsi;
01477
01478
01479 ringCalculator->getRing(eInnerRing)->getPoint(psi,innerRingPoint);
01480 ringCalculator->getRing(eOuterRing)->getPoint(psi,outerRingPoint);
01481
01482
01483
01484
01485
if ( (fabs(outerRingPoint.x()) > mPadPlaneDimension.x()) ||
01486 (fabs(outerRingPoint.y()) > mPadPlaneDimension.y()) ||
01487 (fabs(innerRingPoint.x()) > mPadPlaneDimension.x()) ||
01488 (fabs(innerRingPoint.y()) > mPadPlaneDimension.y()) ) {
01489
01490
continue;
01491 }
01492
01493
01494
01495
01496
01497
01498 StThreeVectorF consPsiVector = outerRingPoint - innerRingPoint;
01499
01500
#ifdef RICH_WITH_PAD_MONITOR
01501
01502
01503
01504
#endif
01505
01506
01507
01508
01509 StThreeVectorF consPsiRefLine = hit - innerRingPoint;
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526 signOfTheta =
01527 sign(consPsiRefLine.x()*consPsiVector.y() -
01528 consPsiRefLine.y()*consPsiVector.x());
01529 sineTheta = abs( (consPsiRefLine.unit()).cross(consPsiVector.unit()) );
01530
01531
01532
double minDistToConsPsiRefLine =
01533 abs(consPsiRefLine) * sineTheta;
01534
01535
01536
01537 anotherIteration =
true;
01538 convergence =
false;
01539 step = 1.*degree;
01540
01541 StThreeVectorF newInnerPointOnRing;
01542 StThreeVectorF newOuterPointOnRing;
01543
double newMinDistToConsPsiRefLine;
01544
01545
if(signOfTheta>0) step *= -1.;
01546
01547 ctr = 0;
01548
while (anotherIteration || ctr<maxIterForRingPsi) {
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564 psi += step;
01565 ctr++;
01566
01567 ringCalculator->getRing(eInnerRing)->getPoint(psi,newInnerPointOnRing);
01568 ringCalculator->getRing(eOuterRing)->getPoint(psi,newOuterPointOnRing);
01569
01570
01571
01572
01573
if( (newInnerPointOnRing.x() == FLT_MAX) ||
01574 (newOuterPointOnRing.x() == FLT_MAX) ) {
01575
01576 psi-=step;
01577 step *=0.5;
01578
continue;
01579 }
01580
01581 consPsiRefLine = hit - newInnerPointOnRing;
01582 consPsiVector = newOuterPointOnRing - newInnerPointOnRing;
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
int signOfNewTheta =
01593 sign(consPsiRefLine.x()*consPsiVector.y() -
01594 consPsiRefLine.y()*consPsiVector.x());
01595 sineTheta = abs( (consPsiRefLine.unit()).cross(consPsiVector.unit()) );
01596
01597
01598 newMinDistToConsPsiRefLine =
01599 abs(consPsiRefLine) * sineTheta;
01600
01601
01602
01603
if( ctr > maxIterForRingPsi )
01604 anotherIteration =
false;
01605
01606
if(newMinDistToConsPsiRefLine < mPrecision) {
01607 convergence =
true;
01608
break;
01609 }
01610
01611
if( (signOfTheta != signOfNewTheta) ||
01612 ( (signOfTheta == signOfNewTheta) &&
01613 (newMinDistToConsPsiRefLine > minDistToConsPsiRefLine) ) ) {
01614
01615 signOfTheta = signOfNewTheta;
01616 step *= -0.5;
01617 }
01618
else {
01619
01620
01621 step = (step>0) ?
01622 min(maxChange,(step*1.2)) : max(-1.*maxChange,step*1.2);
01623
01624
if(newMinDistToConsPsiRefLine < 3.*centimeter) {
01625
01626 step = (step>0) ?
01627 min(1.*degree,step) : max(-1.*degree,step);
01628 }
01629 }
01630
01631 minDistToConsPsiRefLine = newMinDistToConsPsiRefLine;
01632
01633 };
01634
01635
if(!convergence)
continue;
01636
01637
01638
01639
01640
#ifdef RICH_WITH_PAD_MONITOR
01641
01642
01643
#endif
01644
01645
01646
01647
01648
01649
01650
01651
01652 StThreeVectorF lengthOfD = newOuterPointOnRing - newInnerPointOnRing;
01653
01654
01655
01656
01657
01658
01659
01660
01661 StThreeVectorF hitDVector = hit - newInnerPointOnRing;
01662
01663
01664
01665
01666
int signOfD = sign(lengthOfD*hitDVector);
01667
01668
01669
01670
01671
double normalizedD = signOfD * (abs(hitDVector)/abs(lengthOfD));
01672
01673
01674
#ifdef RICH_WITH_PAD_MONITOR
01675
if(normalizedD>0 && normalizedD<1)
01676 mPadMonitor->drawMarker(hit,29,1.2,3);
01677
#endif
01678
01679
01680
01681
01682
01683
01684
01685
double sigmaOfD;
01686
double meanOfD;
01687
01688
01689
01690
01691
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724 meanOfD = 0.5;
01725 sigmaOfD = 0.25;
01726
01727
if( normalizedD<-3. || normalizedD>6. )
continue;
01728
01729
bool inArea =
false;
01730
if(normalizedD>=0 && normalizedD<=1 )
01731 inArea =
true;
01732
01733
double sigma = (normalizedD - meanOfD)/sigmaOfD;
01734
01735
01736
01737
01738
01739
if(particleType == -211 ||
01740 particleType == -321 ||
01741 particleType == -2212 ) {
01742
01743 ringCalculator->
01744 getRing(eInnerRing)->
01745 getTrack()->
01746 addHit((*hitIter),normalizedD,sigma,psi,radPath,quartzPath,particle);
01747 }
01748
else {
01749 cout <<
"StRichPIDMaker::hitfilter()\n";
01750 cout <<
"\tWARNING:\n";
01751 cout <<
"Unknown particle type: ("
01752 << particleType <<
")" << endl;
01753 }
01754
01755
01756 }
01757
01758
01759
01760
01761
01762
01763 }
01764
01765
01766
void StRichPIDMaker::hitFilter(StRichRingCalculator* ringCalculator,
01767 StThreeVectorF& hit,
float& angle,
float& dist) {
01768
01769
01770
01771 ringCalculator->clear();
01772 angle = -999;
01773 dist = -999;
01774 innerDistance = ringCalculator->getInnerDistance(hit,innerAngle);
01775 outerDistance = ringCalculator->getOuterDistance(hit,outerAngle);
01776 meanDistance = ringCalculator->getMeanDistance(hit,meanAngle);
01777 ringWidth = ringCalculator->getRingWidth();
01778
if (ringWidth==0) {
return;}
01779 angle = meanAngle;
01780 dist = ((outerDistance/ringWidth > 1 && (innerDistance/ringWidth < outerDistance/ringWidth )) ?
01781 (-1.0):(1.0))*innerDistance/ringWidth;
01782
return;
01783 }
01784
01785
01786
void StRichPIDMaker::tagMips(
StEvent* tempEvent, StSPtrVecRichHit* hits) {
01787
01788 cout <<
"StRichPIDMaker::tagMips() ---> Tagging Mips using global tracks ..." << endl;
01789
01790 StSPtrVecTrackNode& theTrackNodes = tempEvent->
trackNodes();
01791
for (size_t nodeIndex=0;nodeIndex<theTrackNodes.size();nodeIndex++) {
01792
for (size_t trackIndex=0;
01793 trackIndex<theTrackNodes[nodeIndex]->entries(global);
01794 trackIndex++) {
01795
StTrack* track =
01796 theTrackNodes[nodeIndex]->track(global,trackIndex);
01797
if (track &&
01798 !track->bad() &&
01799 track->flag()>=0 &&
01800 track->fitTraits().numberOfFitPoints(kTpcId) >= 10 ) {
01801
01802 StRichTrack* tempTrack =
new StRichTrack(track,mMagField);
01804
if ( checkTrack(tempTrack) ) {
01805 StThreeVectorF trackPredictor = tempTrack->getProjectedMIP();
01806 StThreeVectorF testThisResidual;
01807
StRichHit* mAssociatedMIP = 0;
01808
float smallestResidual = 3.0*centimeter;
01809
float adcCut = 300;
01810
01811 StSPtrVecRichHitIterator hitIter;
01812
for (hitIter = hits->begin(); hitIter != hits->end(); ++hitIter) {
01813 testThisResidual = ((*hitIter)->local() - trackPredictor);
01814
if ( (testThisResidual.perp() < smallestResidual) &&
01815 ((*hitIter)->charge() > adcCut) ) {
01816 smallestResidual = testThisResidual.perp();
01817 mAssociatedMIP = *hitIter;
01818 }
01819 }
01820
01821 mAssociatedMIP = 0;
01822 }
01823
delete tempTrack;
01824 }
01825 }
01826 }
01827 }
01828
01829
bool StRichPIDMaker::checkEvent(
StEvent* event) {
01830
01831
01832
01833
01834
01835
if (!event) {
01836 cout <<
"StRichPIDMaker::checkEvent()\n";
01837 cout <<
"\tERROR: Bad Event. Skipping..." << endl;
01838
return false;
01839 }
01840
01841
if(!event->
primaryVertex()) {
01842 cout <<
"StRichPIDMaker::checkEvent()\n";
01843 cout <<
"\tERROR: No Vertex. Skipping..." << endl;
01844
return false;
01845 }
01846
01847 mVertexPos = event->
primaryVertex()->
position();
01848 mEventN = event->
id();
01849 mEventRunId = event->
runId();
01850
01851
01852
if( fabs(mVertexPos.z()) > mVertexWindow) {
01853 cout <<
"StRichPIDMaker::checkEvent()\n";
01854 cout <<
"\tVertex Cut not satisfied (";
01855 cout << (mVertexWindow/centimeter) <<
" cm)\n";
01856 cout <<
"\tz=" << mVertexPos.z() << endl;
01857
return false;
01858 }
01859
01860
01861
01862
01863 mMagField = 2.49117;
01864
if (event->
summary()) {
01865 mMagField = event->
summary()->
magneticField();
01866 cout <<
" B field = " << mMagField << endl;
01867 }
01868
else {
01869 cout <<
"StRichPIDMaker::checkEvent().\n";
01870 cout <<
"\tWARNING!\n";
01871 cout <<
"\tCannot get B field from event->summary(). \n";
01872 cout <<
"\tUse B= " << mMagField << endl;
01873 }
01874
01875
return true;
01876 }
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888
01889
01890
01891
01892
01893
01894
bool StRichPIDMaker::checkTrack(
StTrack* track) {
01895
01896
bool status =
true;
01897
int bitmask = 0;
01898
if (track->bad()) {
01899 status =
false;
01900 bitmask += 1<<0;
01901
return status;
01902 }
01903
01904
if (!track->geometry()) {
01905 status =
false;
01906 bitmask += 1<<1;
01907 }
01908
01909
if (track->geometry()->helix().distance(mVertexPos) > mDcaCut) {
01910 status =
false;
01911 bitmask += 1<<2;
01912 }
01913
01914
if (track->fitTraits().numberOfFitPoints(kTpcId) < mFitPointsCut) {
01915 status =
false;
01916 bitmask += 1<<3;
01917 }
01918
01919
if (fabs(track->geometry()->momentum().pseudoRapidity()) > mEtaCut) {
01920 status =
false;
01921 bitmask += 1<<4;
01922 }
01923
01924
if (track->geometry()->momentum().perp() < mPtCut) {
01925 status =
false;
01926 bitmask += 1<<5;
01927 }
01928
01929
01930
01931
#ifdef myRICH_WITH_NTUPLE
01932
01933
01934
#ifdef myRICH_WITH_MC
01935
float distHits[35];
01936
#else
01937
float distHits[34];
01938
#endif
01939
01940 distHits[0] = 0;
01941 distHits[1] = 0;
01942 distHits[2] = 0;
01943 distHits[3] = 0;
01944 distHits[4] = 0;
01945 distHits[5] = 0;
01946 distHits[6] = 0;
01947
01948
01949 distHits[7] = 0;
01950 distHits[8] = 0;
01951 distHits[9] = 0;
01952
01953
01954 distHits[10] = 0;
01955 distHits[11] = 0;
01956
01957
01958 distHits[12] = 0;
01959 distHits[13] = 0;
01960
01961
01962 distHits[14] = track->geometry()->momentum().x();
01963 distHits[15] = track->geometry()->momentum().y();
01964 distHits[16] = track->geometry()->momentum().z();
01965
01966
01967
01968 distHits[17] = 0;
01969 distHits[18] = mEventN;
01970
01971 distHits[19] = -2.0;
01972
01973 distHits[20] = 0;
01974 distHits[21] = 0;
01975 distHits[22] = bitmask;
01976
01977 distHits[23] = 0;
01978 distHits[24] = 0;
01979 distHits[25] = 0;
01980
01981 distHits[26] = track->geometry()->momentum().mag();
01982 distHits[27] = track->geometry()->charge();
01983 distHits[28] = mVertexPos.z();
01984 distHits[29] = 0;
01985 distHits[30] = 0;
01986 distHits[31] = 0;
01987 distHits[32] = mEventRunId;
01988 distHits[33] = 0;
01989
#ifdef myRICH_WITH_MC
01990
distHits[34] = 0;
01991
#endif
01992
01993 distup->Fill(distHits);
01994
01995
#endif
01996
01997
return status;
01998 }
01999
02000
bool StRichPIDMaker::checkTrack(StRichTrack* track) {
02001
02002
bool status =
true;
02003 StThreeVectorF extrapolatedPosition = track->getProjectedMIP();
02004 StThreeVectorF impactPoint = track->getImpactPoint();
02005
02006
float bitmask = 0;
02007
if (fabs(extrapolatedPosition.x()) > (mPadPlaneDimension.x() - mPadPlaneCut)) {
02008 status =
false;
02009 bitmask += ::pow(2.,6);
02010 }
02011
02012
if ( fabs(extrapolatedPosition.y()) > (mPadPlaneDimension.y() - mPadPlaneCut) ) {
02013 status =
false;
02014 bitmask += ::pow(2.,7);
02015 }
02016
02017
if (fabs(extrapolatedPosition.x()) < (mPadPlaneCut) ) {
02018 status =
false;
02019 bitmask += ::pow(2.,8);
02020 }
02021
02022
if (fabs(extrapolatedPosition.y()) < (mPadPlaneCut) ) {
02023 status =
false;
02024 bitmask += ::pow(2.,9);
02025 }
02026
02027
if (fabs(impactPoint.x()) > (mRadiatorDimension.x() - mRadiatorCut) ) {
02028 status =
false;
02029 bitmask += ::pow(2.,10);
02030 }
02031
02032
if (fabs(impactPoint.y()) > (mRadiatorDimension.y() - mRadiatorCut) ) {
02033 status =
false;
02034 bitmask += ::pow(2.,11);
02035 }
02036
02037
if (fabs(impactPoint.x()) < (mRadiatorCut)) {
02038 status =
false;
02039 bitmask += ::pow(2.,12);
02040 }
02041
02042
if (fabs(impactPoint.y()) < (mRadiatorCut)) {
02043 status =
false;
02044 bitmask += ::pow(2.,13);
02045 }
02046
02047
if (track->getPathLength()<0 || track->getPathLength()>mPathCut/centimeter) {
02048 status =
false;
02049 bitmask += ::pow(2.,14);
02050 }
02051
02052
if (track->getLastHit().perp()<mLastHitCut) {
02053 status =
false;
02054 bitmask += ::pow(2.,15);
02055 }
02056
02057
02058
02059
02060
#ifdef myRICH_WITH_NTUPLE
02061
02062
#ifdef myRICH_WITH_MC
02063
float distHits[35];
02064
#else
02065
float distHits[34];
02066
#endif
02067
02068
02069
float amipq = -999;
02070
if (track->getAssociatedMIP()) {
02071 amipq = track->getAssociatedMIP()->charge();
02072 }
02073
02074 distHits[0] = 0;
02075 distHits[1] = 0;
02076 distHits[2] = 0;
02077 distHits[3] = 0;
02078 distHits[4] = 0;
02079 distHits[5] = 0;
02080 distHits[6] = 0;
02081
02082
02083 distHits[7] = 0;
02084 distHits[8] = 0;
02085 distHits[9] = 0;
02086
02087
02088 distHits[10] = 0;
02089 distHits[11] = 0;
02090
02091
02092 distHits[12] = track->getProjectedMIP().x();
02093 distHits[13] = track->getProjectedMIP().y();
02094
02095 distHits[14] = track->getStTrack()->geometry()->momentum().x();
02096 distHits[15] = track->getStTrack()->geometry()->momentum().y();
02097 distHits[16] = track->getStTrack()->geometry()->momentum().z();
02098
02099
02100
02101 distHits[17] = 0;
02102 distHits[18] = mEventN;
02103
02104 distHits[19] = -1.0;
02105
02106 distHits[20] = 0;
02107 distHits[21] = 0;
02108 distHits[22] = bitmask;
02109
02110 distHits[23] = 0;
02111 distHits[24] = 0;
02112 distHits[25] = 0;
02113
02114 distHits[26] = track->getMomentum().mag();
02115 distHits[27] = track->getStTrack()->geometry()->charge();
02116 distHits[28] = mVertexPos.z();
02117 distHits[29] = 0;
02118 distHits[30] = 0;
02119 distHits[31] = 0;
02120 distHits[32] = mEventRunId;
02121 distHits[33] = amipq;
02122
02123
02124
#ifdef myRICH_WITH_MC
02125
distHits[34] = 0;
02126
#endif
02127
02128
02129 distup->Fill(distHits);
02130
#endif
02131
02132
02133
return status;
02134
02135
02136
02137
02138
02139
02140
02141
02142
02143
02144
02145
02146
02147
02148
02149
02150
02151
02152
02153
02154
02155
02156 }
02157
02158
bool StRichPIDMaker::checkTrackMomentum(
float mag) {
02159
if(mag<mThresholdMomentum)
02160
return false;
02161
02162
return true;
02163 }
02164
02165
02166
bool StRichPIDMaker::checkHit(
StRichHit* hit) {
02167
02168
02169
02170
if (hit && hit->charge()<mAdcCut) {
return true;}
02171
return false;
02172 }
02173
02174
02175
02176
02177
void StRichPIDMaker::fillPIDTraits(StRichRingCalculator* ringCalc) {
02178
02179
02180
02181
02182
02183
02184
if (!ringCalc) {
02185 cout <<
"StRichPIDMaker::fillPIDTraits()\n";
02186 cout <<
"\tRingCalculator Pointer is lost\n";
02187 cout <<
"\tReturning" << endl;
02188
return;
02189 }
02190
02191
if (!ringCalc->getRing(eInnerRing)) {
02192 cout <<
"StRichPIDMaker::fillPIDTraits()\n";
02193 cout <<
"\tRingCalculator lost inner ring\n";
02194 cout <<
"\tReturning" << endl;
02195
return;
02196 }
02197
02198
02199
02200
02201 StRichTrack* richTrack = ringCalc->getRing(eInnerRing)->getTrack();
02202
if(!richTrack) {
02203 cout <<
"StRichPIDMaker::fillPidTraits()\n";
02204 cout <<
"\tWARNING Cannot get StRichTrack:\n";
02205 cout <<
"\tReturning..." << endl;
02206
return;
02207 }
02208
02209
if(!richTrack->getStTrack()) {
02210 cout <<
"StRichPIDMaker::fillPidTraits()\n";
02211 cout <<
"\tWARNING Cannot get StTrack from StRichTrack\n";
02212 cout <<
"\tReturning..." << endl;
02213
return;
02214 }
02215
02216
if(!richTrack->getStTrack()->detectorInfo()) {
02217 cout <<
"StRichPIDMaker::fillPidTraits()\n";
02218 cout <<
"\tWARNING Cannot get DetectorInfo from StTrack\n";
02219 cout <<
"\tReturning..." << endl;
02220
return;
02221 }
02222
02223 StParticleDefinition* part =
02224 ringCalc->getRing(eInnerRing)->getParticleType();
02225
02226
unsigned int totalHitsInArea = 0;
02227
unsigned int hitsInConstantAngle = 0;
02228
unsigned int hitsInConstantArea = 0;
02229
unsigned int sig1 = 0;
02230
unsigned int sig2 = 0;
02231
02232
02233
02234
02235
02236
02237
02238
if ( richTrack->fastEnough(part) &&
02239 richTrack->isGood(part) ) {
02240
02241
StRichPid* pid =
new StRichPid();
02242 pid->
setRingType(part);
02243
02244
02245
02246
02247 pid->
setTotalArea(ringCalc->getTotalConstantArea());
02248 pid->
setTotalAzimuth(ringCalc->getTotalConstantAngle());
02249
02250
02251
02252
02253
02254 pid->
setTruncatedArea(ringCalc->getTotalConstantAreaOnActivePadPlane());
02255 pid->
setTruncatedAzimuth(ringCalc->getTotalConstantAngleOnActivePadPlane());
02256
02257 vector<StRichRingHit*> hits = richTrack->getRingHits(part);
02258
02259
02260
02261
02262
02263
02264
for (size_t i=0; i<hits.size(); i++) {
02265
02266
StRichHit* theCurrentHit = hits[i]->getHit();
02267 pid->
addHit(theCurrentHit);
02268 richTrack->getStTrack()->detectorInfo()->addHit(theCurrentHit);
02269
02270
float normalizedD = hits[i]->getDist();
02271
float sigma = hits[i]->getNSigma();
02272
float psi = hits[i]->getAngle();
02273
02274
02275
02276
02277 pid->
addPhotonInfo(
new StRichPhotonInfo(normalizedD, sigma, psi));
02278
02279
02280
02281
02282
bool inArea =
false;
02283
bool inConstantAngle =
false;
02284
bool inConstantArea =
false;
02285
02286
if ( (normalizedD >= 0) && (normalizedD <= 1) ) {
02287 inArea =
true;
02288 totalHitsInArea++;
02289 }
02290
02291 pid->
setConstantAreaCut(ringCalc->getConstantAreaAngle());
02292
02293
if ( fabs(psi) > ringCalc->getConstantAreaAngle()) {
02294 inConstantAngle =
true;
02295 hitsInConstantAngle++;
02296 }
02297
02298
if(inArea && inConstantAngle) {
02299 inConstantArea =
true;
02300 hitsInConstantArea++;
02301 }
02302
02303
if(part == pion) {
02304
02305
if( theCurrentHit->
isSet(eInMultipleCAreaPi) )
continue;
02306
02307
if( theCurrentHit->
isSet(eInAreaPi) ||
02308 theCurrentHit->
isSet(eInConstantAnglePi) ) {
02309
02310
02311 theCurrentHit->
setBit(eMultiplyAssigned);
02312 }
02313
02314
if(inArea) {
02315
if( theCurrentHit->
isSet(eInAreaPi) ) {
02316 theCurrentHit->
setBit(eInMultipleAreaPi);
02317 }
02318
else {
02319 theCurrentHit->
setBit(eInAreaPi);
02320 }
02321 }
02322
02323
if(inConstantAngle) {
02324
if( theCurrentHit->
isSet(eInConstantAnglePi) ) {
02325 theCurrentHit->
setBit(eInMultipleCAnglePi);
02326 }
02327
else {
02328 theCurrentHit->
setBit(eInConstantAnglePi);
02329 }
02330 }
02331
02332
if( inConstantAngle && !theCurrentHit->
isSet(eInMultipleCAnglePi) ) {
02333
if( fabs(sigma)<1 ) {theCurrentHit->
setBit(e1SigmaPi);sig1++;}
02334
if( fabs(sigma)<2 ) {theCurrentHit->
setBit(e2SigmaPi);sig2++;}
02335 }
02336
02337
02338
if(inConstantArea) {
02339
if( theCurrentHit->
isSet(eInConstantAreaPi) ) {
02340 theCurrentHit->
setBit(eInMultipleCAreaPi);
02341 }
02342
else {
02343 theCurrentHit->
setBit(eInConstantAreaPi);
02344 }
02345 }
02346
02347 }
02348
02349
02350
if(part == kaon) {
02351
if( theCurrentHit->
isSet(eInMultipleCAreaK) )
continue;
02352
02353
if( theCurrentHit->
isSet(eInAreaK) ||
02354 theCurrentHit->
isSet(eInConstantAngleK) ) {
02355
02356
02357 theCurrentHit->
setBit(eMultiplyAssigned);
02358 }
02359
02360
if(inArea) {
02361
if( theCurrentHit->
isSet(eInAreaK) ) {
02362 theCurrentHit->
setBit(eInMultipleAreaK);
02363 }
02364
else {
02365 theCurrentHit->
setBit(eInAreaK);
02366 }
02367 }
02368
02369
if(inConstantAngle) {
02370
if( theCurrentHit->
isSet(eInConstantAngleK) ) {
02371 theCurrentHit->
setBit(eInMultipleCAngleK);
02372 }
02373
else {
02374 theCurrentHit->
setBit(eInConstantAngleK);
02375 }
02376 }
02377
02378
if( inConstantAngle && !theCurrentHit->
isSet(eInMultipleCAngleK) ) {
02379
if( fabs(sigma)<1 ) {theCurrentHit->
setBit(e1SigmaK);sig1++;}
02380
if( fabs(sigma)<2 ) {theCurrentHit->
setBit(e2SigmaK);sig2++;}
02381 }
02382
02383
if(inConstantArea) {
02384
if( theCurrentHit->
isSet(eInConstantAreaK) ) {
02385 theCurrentHit->
setBit(eInMultipleCAreaK);
02386 }
02387
else {
02388 theCurrentHit->
setBit(eInConstantAreaK);
02389 }
02390 }
02391
02392 }
02393
02394
if(part == proton) {
02395
if( theCurrentHit->
isSet(eInMultipleCAreap) )
continue;
02396
02397
if( theCurrentHit->
isSet(eInAreap) ||
02398 theCurrentHit->
isSet(eInConstantAnglep) ) {
02399
02400
02401
02402 theCurrentHit->
setBit(eMultiplyAssigned);
02403 }
02404
02405
if(inArea) {
02406
if( theCurrentHit->
isSet(eInAreap) ) {
02407 theCurrentHit->
setBit(eInMultipleAreap);
02408 }
02409
else {
02410 theCurrentHit->
setBit(eInAreap);
02411 }
02412 }
02413
02414
if(inConstantAngle) {
02415
if( theCurrentHit->
isSet(eInConstantAnglep) ) {
02416 theCurrentHit->
setBit(eInMultipleCAnglep);
02417 }
02418
else {
02419 theCurrentHit->
setBit(eInConstantAnglep);
02420 }
02421 }
02422
02423
if(inConstantAngle && !theCurrentHit->
isSet(eInMultipleCAnglep) ) {
02424
if( fabs(sigma)<1 ) {theCurrentHit->
setBit(e1Sigmap);sig1++;}
02425
if( fabs(sigma)<2 ) {theCurrentHit->
setBit(e2Sigmap);sig2++;}
02426 }
02427
02428
if(inConstantArea) {
02429
if( theCurrentHit->
isSet(eInConstantAreap) ) {
02430 theCurrentHit->
setBit(eInMultipleCAreap);
02431 }
02432
else {
02433 theCurrentHit->
setBit(eInConstantAreap);
02434 }
02435 }
02436
02437 }
02438
02439
02440
02441
02442
02443
02444
02445
02446
02447
02448
02449
02450
02451
02452
02453
02454
02455
02456
02457
02458
02459
02460
02461
02462
02463
02464
02465
02466
02467
02468
02469
02470
02471
02472
02473
02474
02475
02476 }
02477
02478
02479
02480 pid->
setTotalDensity(hitsInConstantArea/pid->
getTotalArea());
02481 pid->
setTruncatedDensity(hitsInConstantArea/pid->
getTruncatedArea());
02482
02483 pid->
setTotalHits(totalHitsInArea);
02484 pid->
setTruncatedHits(hitsInConstantArea);
02485
02486 StThreeVectorD residual(-999.,-999.,-999.);
02487
if (!richTrack->getAssociatedMIP()) {
02488 cout <<
"StRichPIDMaker::fillPIDTraits()\n";
02489 cout <<
"\tWARNING Rich Track has no AssociatedMIP*\n";
02490 cout <<
"\tp= " << richTrack->getStTrack()->geometry()->momentum().mag() << endl;
02491 }
02492
else {
02493 residual = richTrack->getProjectedMIP() - richTrack->getAssociatedMIP()->local();
02494 }
02495
02496
02497
02498
02499
02500
02501
02502
02503 pid->
setMipResidual(residual);
02504
02505
02506
02507
02508
02509 richTrack->getPidTrait()->addPid(pid);
02510
02511 }
02512
02513 }
02514
02515
bool StRichPIDMaker::reprocessTheTraits(
StRichPidTraits* traits)
02516 {
02517
02518
02519
02520
const StSPtrVecRichPid& allThePids = traits->
getAllPids();
02521
for(size_t ii=0; ii<allThePids.size(); ii++) {
02522
StRichPid* pid = allThePids[ii];
02523
if(!pid) {
02524 cout <<
"StRichPIDMaker::reprocessTheTraits()\n";
02525 cout <<
"\tERROR cannot get the StRichPid\n";
02526 cout <<
"\tcontinuing..." << endl;
02527
continue;
02528 }
02529
02530
const StPtrVecRichHit& hit = pid->
getAssociatedRichHits();
02531
02532
unsigned int hitsInConstantArea = 0;
02533
for(size_t jj=0; jj<hit.size(); jj++) {
02534
switch(pid->
getParticleNumber()) {
02535
case -211:
02536
02537
02538
02539
02540
02541
02542
02543
02544
02545
02546
if( hit[jj]->isSet(eInMultipleCAreaPi) )
continue;
02547
if( hit[jj]->isSet(eInConstantAreaPi) ) {
02548 hitsInConstantArea++;
02549 }
02550
break;
02551
02552
case -321:
02553
02554
02555
02556
02557
02558
02559
02560
02561
02562
02563
if( hit[jj]->isSet(eInMultipleCAreaK) )
continue;
02564
if( hit[jj]->isSet(eInConstantAreaK) ) {
02565 hitsInConstantArea++;
02566 }
02567
break;
02568
02569
case -2212:
02570
02571
02572
02573
02574
02575
02576
02577
02578
02579
02580
if( hit[jj]->isSet(eInMultipleCAreap) )
continue;
02581
if( hit[jj]->isSet(eInConstantAreap) ) {
02582 hitsInConstantArea++;
02583 }
02584
break;
02585
02586
default:
02587 cout <<
"StRichPIDMaker::reprocessTheTraits()\n";
02588 cout <<
"\tERROR Unknown Particle Type\n";
02589 cout <<
"\tContinuing..." << endl;
02590 }
02591
02592 }
02593
02594
if(pid->
getTruncatedHits() != hitsInConstantArea) {
02595
02596
02597
if(hitsInConstantArea > pid->
getTruncatedHits()) {
02598
02599
02600
02601
break;
02602 }
02603
02604 pid->
setTruncatedHits(hitsInConstantArea);
02605 pid->
setTruncatedDensity(hitsInConstantArea/pid->
getTruncatedArea());
02606 }
02607 }
02608
02609
02610
02611
02612
02613
02614
return true;
02615 }
02616
02617
void StRichPIDMaker::fillRichSoftwareMonitor(
StEvent* evnt) {
02618
02619
StSoftwareMonitor* monitor = evnt->
softwareMonitor();
02620
if (monitor) {
02621
StRichSoftwareMonitor* richMonitor = monitor->
rich();
02622
if (richMonitor) {
02623 richMonitor->
setNumberOfTracksCrossing(mRichTracks);
02624 richMonitor->
setNumberOfTracksAbove1Gev(mNumberOf1GeV);
02625 richMonitor->
setNumberOfHitsInRings(mNumberOfRingHits);
02626 }
02627 }
02628 }
02629
02630
void StRichPIDMaker::drawPadPlane(
StEvent* rEvent,
bool kCreatePsFile) {
02631
02632
#ifdef RICH_WITH_PAD_MONITOR
02633
02634
02635
02636
02637
02638
02639 mPadMonitor = StRichPadMonitor::getInstance(mGeometryDb);
02640 mPadMonitor->clearTracks();
02641 mPadMonitor->drawZVertex(mVertexPos.z(),mNumberOfPrimaries,mRichTracks);
02642 mPadMonitor->drawEventInfo(rEvent->
runId(),rEvent->
id());
02643 mPadMonitor->drawFileName(fileName);
02644
02645
for (size_t trackIndex=0; trackIndex<mListOfStRichTracks.size(); trackIndex++) {
02646 mPadMonitor->addTrack(mListOfStRichTracks[trackIndex]);
02647 }
02648
02649 mPadMonitor->drawRings();
02650
02651
02652 mPadMonitor->hiLiteHits(eInAreap,proton);
02653
02654
02655
02656 mPadMonitor->hiLiteHits(e2Sigmap,proton);
02657
02658 mPadMonitor->drawRingInfo();
02659 mPadMonitor->update();
02660
02661
if (kCreatePsFile) {
02662 cout <<
"print it...." << endl;
02663 mPadMonitor->printCanvas(
"~anyDirectory",fileName,rEvent->
id());
02664 }
02665
#endif
02666
}
02667
02668
02669
02670
02671
02672
02673
02674
void StRichPIDMaker::printCutParameters(ostream& os)
const
02675
{
02676 os <<
"==============================================" << endl;
02677 os <<
"StRichPIDMaker::printCutParameters()" << endl;
02678 os <<
"----------------------------------------------" << endl;
02679 os <<
"Event Level:" << endl;
02680 os <<
"\tVertexWindow = " << (mVertexWindow/centimeter) <<
" cm" << endl;
02681 os <<
"Hit Level:" << endl;
02682 os <<
"\tAdcCut = " << (mAdcCut) << endl;
02683 os <<
"Track Level:" << endl;
02684 os <<
"\tPtCut = " << (mPtCut/GeV) <<
" GeV/c" << endl;
02685 os <<
"\tEtaCut = " << mEtaCut << endl;
02686 os <<
"\tLastHitCut = " << (mLastHitCut/centimeter) <<
" cm" << endl;
02687 os <<
"\tDcaCut = " << (mDcaCut/centimeter) <<
" cm" << endl;
02688 os <<
"\tFitPointsCut = " << mFitPointsCut << endl;
02689 os <<
"\tPathCut = " << (mPathCut/centimeter) <<
" cm" << endl;
02690 os <<
"\tPadPlaneCut = " << (mPadPlaneCut/centimeter) <<
" cm" << endl;
02691 os <<
"\tRadiatorCut = " << (mRadiatorCut/centimeter) <<
" cm" << endl;
02692 os <<
"\tThreshMom = " << (mThresholdMomentum/GeV) <<
" GeV/c" << endl;
02693 os <<
"----------------------------------------------" << endl;
02694 os <<
"++++++++++++++++++++++++++++++++++++++++++++++" << endl;
02695 os <<
"Convergence Precision:" << endl;
02696 os <<
"\tPrecision = " << (mPrecision/micrometer) <<
" um" << endl;
02697 os <<
"----------------------------------------------" << endl;
02698
02699
02700
02701
02702
02703
02704
02705
02706
02707
02708
02709
02710
02711
02712
02713
02714
02715
02716
02717
02718 }
02719
02720
02721
void StRichPIDMaker::setVertexWindow(
float window) {
02722 cout <<
"StRichPIDMaker::setVertexWindow() " << window << endl;
02723 mVertexWindow = window;
02724 }
02725
02726
02727
void StRichPIDMaker::setAdcCut(
int cut) {mAdcCut = cut;}
02728
02729
02730
void StRichPIDMaker::setLastHitCut(
float cut) {mLastHitCut = cut;}
02731
void StRichPIDMaker::setDcaCut(
float cut) {mDcaCut = cut;}
02732
void StRichPIDMaker::setPtCut(
float cut) {mPtCut = cut;}
02733
void StRichPIDMaker::setEtaCut(
float cut) {mEtaCut = cut;}
02734
void StRichPIDMaker::setFitPointsCut(
int cut) {mFitPointsCut = cut;}
02735
void StRichPIDMaker::setPathLengthCut(
float cut) {mPathCut = cut;}
02736
void StRichPIDMaker::setPadPlaneCut(
float cut) {mPadPlaneCut = cut;}
02737
void StRichPIDMaker::setRadiatorCut(
float cut) {mRadiatorCut = cut;}
02738
float StRichPIDMaker::getHitSigma(
float hitDist) {
02739
float sigma = 0.4;
02740
float mean = 0.45;
02741
return fabs(hitDist-mean)/sigma;
02742 }
02743
02744
02745
void StRichPIDMaker::DefineSaveDirectory(
char* directory) {
02746 mySaveDirectory=directory;
02747 }
02748
02749
02750
void StRichPIDMaker::setFileName(
char * name){
02751 fileName = name;
02752 }
02753
02754
02755
void StRichPIDMaker::setWavelengthRange(
double shortest ,
double longest) {
02756 mShortWave = shortest;
02757 mLongWave = longest;
02758 mMaterialDb = StRichMaterialsDb::getDb();
02759 mMaterialDb->setWavelengthRange(mShortWave,mLongWave);
02760 }
02761
02762
02763
#ifdef myRICH_WITH_MC
02764
void StRichPIDMaker::fillMcPixelNtuple(
const StSPtrVecRichPixel* pixels) {
02765
02766
if (!pixels)
return;
02767
02768
02769
StRichMCPixel* monteCarloRichPixel = 0;
02770
for (StSPtrVecRichPixelConstIterator iter = pixels->begin();iter != pixels->end(); ++iter) {
02771
02772 monteCarloRichPixel = dynamic_cast<StRichMCPixel*>(*iter);
02773
if (monteCarloRichPixel) {
02774 Long_t gid[4] = {0,0,0,0};
02775 Float_t gq[4] = {0,0,0,0};
02776 Long_t gproc[4] = {0,0,0,0};
02777
02778
unsigned int n = monteCarloRichPixel->
contributions();
02779
unsigned int limit = (n>4)?(4):(n);
02780
for (
int i=0;i<limit;i++) {
02781 gid[i] = monteCarloRichPixel->
getMCInfo()[i]->gid();
02782 gq[i] = monteCarloRichPixel->
getMCInfo()[i]->charge();
02783 gproc[i] = monteCarloRichPixel->
getMCInfo()[i]->process();
02784 }
02785
02786 geantPixelNtuple->Fill(monteCarloRichPixel->
adc(),monteCarloRichPixel->
contributions(),
02787 gid[0],gid[1],gid[2],gid[3],gq[0],gq[1],gq[2],gq[3],
02788 gproc[0],gproc[1],gproc[2],gproc[3]);
02789 }
02790 }
02791 }
02792
#endif
02793
02794
02795
02796
02797
#ifdef myRICH_WITH_MC
02798
void StRichPIDMaker::fillGeantHitNtuple() {
02799
02800 StRichMCTrack* richMcTrack=0;
02801
02802
float constAngle=-999;
02803
for (size_t trackIndex=0; trackIndex<mListOfStRichTracks.size();trackIndex++) {
02804 richMcTrack = dynamic_cast<StRichMCTrack*>(mListOfStRichTracks[trackIndex]);
02805
if (richMcTrack) {
02806
if (mListOfStRichTracks[trackIndex]->getPidTrait() &&
02807 mListOfStRichTracks[trackIndex]->getPidTrait()->getPid(pion)) {
02808 constAngle = mListOfStRichTracks[trackIndex]->getPidTrait()->getPid(pion)->getTruncatedAzimuth();
02809 }
02810
02811 vector<StMcRichHit*> tempHits = richMcTrack->getGeantPhotons();
02812
float wave1,psi1,z1;
02813
float wave2,psi2,z2;
02814
float wave1save,wave2save;
02815
float psi1save,psi2save;
02816
float z1save,z2save;
02817
float gtheta1,gtheta2;
02818
float thetap1,thetap2;
02819
float x1,y1,x2,y2;
02820
02821
for (
int i=0;i<tempHits.size();i++) {
02822
for (
int j=i+1;j<tempHits.size();j++) {
02823
02824 getGeantPhotonInfo(richMcTrack,tempHits[i]->parentTrack(),wave1,psi1,z1,gtheta1,thetap1);
02825 getGeantPhotonInfo(richMcTrack,tempHits[j]->parentTrack(),wave2,psi2,z2,gtheta2,thetap2);
02826
02827
if (fabs(psi1)>constAngle && fabs(psi2)>constAngle) {
02828
02829
if (psi1<0) psi1 = psi1 + 2.0*M_PI;
02830
if (psi2<0) psi2 = psi2 + 2.0*M_PI;
02831
if ( fabs(psi1-psi2) < fabs(psi1save-psi2save)) {
02832 psi1save=psi1;
02833 psi2save=psi2;
02834 wave1save=wave1;
02835 wave2save=wave2;
02836 z1save = z1;
02837 z2save = z2;
02838 x1 = tempHits[i]->position().x();
02839 y1 = tempHits[i]->position().y();
02840 x2 = tempHits[j]->position().x();
02841 y2 = tempHits[j]->position().y();
02842 }
02843 }
02844 }
02845 }
02846
02847
float array[13];
02848 array[0] = richMcTrack->getMomentum().mag();
02849 array[1] = richMcTrack->getTheta()/degree;
02850 array[2] = wave1save/nanometer;
02851 array[3] = wave2save/nanometer;
02852 array[4] = psi1save/degree;
02853 array[5] = psi2save/degree;
02854 array[6] = z1save;
02855 array[7] = z2save;
02856 array[8] = x1;
02857 array[9] = y1;
02858 array[10] = x2;
02859 array[11] = y2;
02860 array[12] = constAngle/degree;
02861 geantCloseHitNtuple->Fill(array);
02862 }
02863 }
02864 }
02865
#endif
02866
02867
02868
02869
02870
02871
02872
#ifdef myRICH_WITH_MC
02873
void StRichPIDMaker::fillMcPhotonNtuple(
StMcEvent* mcevent,
02874
const StSPtrVecRichCluster* clusters,
02875
const StSPtrVecRichHit* richHits) {
02876
02877
if (!mcevent || !richHits || !clusters)
return;
02878
02879
02880 St_DataSet* dsGeant = GetDataSet(
"geant");
02881
if(!dsGeant || !dsGeant->GetList()) {
02882 dsGeant = GetDataSet(
"event/geant/Event");
02883
if(!dsGeant || !dsGeant->GetList()) {
return;}
02884 }
02885
02886 St_DataSetIter geantDstI(dsGeant);
02887 St_g2t_track *g2t_track = (St_g2t_track *) geantDstI(
"g2t_track");
02888
02889 StRichMCTrack* richMcTrack = 0;
02890 StParticleDefinition* geantParticle = 0;
02891
02892
StRichMCHit* monteCarloRichHit = 0;
02893
StMcTrack* theHitsStMcTrack = 0;
02894
StMcTrack* theHitsParentStMcTrack = 0;
02895
02896
for (size_t trackIndex=0; trackIndex<mListOfStRichTracks.size();trackIndex++) {
02897
02898 richMcTrack = dynamic_cast<StRichMCTrack*>(mListOfStRichTracks[trackIndex]);
02899 geantParticle = richMcTrack->getStMcTrack()->particleDefinition();
02900
02901
if (richMcTrack && geantParticle) {
02902
02903 richMcTrack->useTPCInfo();
02904 StRichRingCalculator* TPC_RingCalc =
new StRichRingCalculator(richMcTrack,geantParticle);
02905 TPC_RingCalc->calculateArea();
02906
02907
02908
02909
02910 richMcTrack->useGeantInfo();
02911 StRichRingCalculator* GEANT_RingCalc =
new StRichRingCalculator(richMcTrack,geantParticle);
02912 GEANT_RingCalc->calculateArea();
02913
02914
02915
02916
02917 richMcTrack->useTPCInfo();
02918
02919
float defaultValue = -999.0;
02920
float mcWave,mcPsi,mcZ,mcTheta,mcPhotTheta;
02921
int signalPhoton;
02922
02923
02924 StSPtrVecRichHitConstIterator iter;
02925
for (iter = richHits->begin();iter != richHits->end(); ++iter) {
02926
02927 monteCarloRichHit = dynamic_cast<StRichMCHit*>(*iter);
02928 theHitsStMcTrack = getStMcTrack(monteCarloRichHit, mcevent, g2t_track);
02929
02930
if (monteCarloRichHit && theHitsStMcTrack) {
02931
02932
if (theHitsStMcTrack->
geantId() == 50) {theHitsParentStMcTrack = theHitsStMcTrack->
parent();}
02933
else {theHitsParentStMcTrack = theHitsStMcTrack;}
02934
02935
02936 signalPhoton = 0;
02937
if (monteCarloRichHit->
getMCInfo().
process()==ePhoton &&
02938 theHitsParentStMcTrack == richMcTrack->getStMcTrack()
02939 && theHitsStMcTrack->
geantId()==50) {
02940 signalPhoton=1;
02941 }
02942
02943 mcWave = defaultValue; mcPsi = defaultValue;
02944 mcZ = defaultValue; mcTheta = defaultValue;
02945 mcPhotTheta = defaultValue;
02946 getGeantPhotonInfo(richMcTrack,theHitsStMcTrack,mcWave,mcPsi,mcZ,mcTheta,mcPhotTheta);
02947 StThreeVectorF geantRichHit = getTheGeantHitOnPadPlane(theHitsStMcTrack,monteCarloRichHit->
local());
02948
02949 Float_t photonArray[54];
02950
02951 photonArray[0] = richMcTrack->getStTrack()->geometry()->charge();
02952 photonArray[1] = richMcTrack->getMomentum().x();
02953 photonArray[2] = richMcTrack->getMomentum().y();
02954 photonArray[3] = richMcTrack->getMomentum().z();
02955 photonArray[4] = richMcTrack->getImpactPoint().x();
02956
02957 photonArray[5] = richMcTrack->getImpactPoint().y();
02958 photonArray[6] = richMcTrack->getGeantImpactPointAtRadiator().x();
02959 photonArray[7] = richMcTrack->getGeantImpactPointAtRadiator().y();
02960 photonArray[8] = richMcTrack->getProjectedMIP().x();
02961 photonArray[9] = richMcTrack->getProjectedMIP().y();
02962
02963
StRichMCHit* tempHit = dynamic_cast<StRichMCHit*>(richMcTrack->getAssociatedMIP());
02964
if (tempHit) {
02965
02966 photonArray[10] = tempHit->
getMCInfo().
id();
02967 photonArray[11] = tempHit->
getMCInfo().
process();
02968 photonArray[12] = tempHit->
charge();
02969 photonArray[13] = tempHit->
local().x();
02970 photonArray[14] = tempHit->
local().y();
02971 photonArray[15] = (*clusters)[tempHit->
clusterNumber()]->numberOfPads();
02972 }
02973
02974 tempHit = richMcTrack->getGeantRecoMIP();
02975
if (tempHit) {
02976 photonArray[16] = tempHit->
getMCInfo().
id();
02977 photonArray[17] = tempHit->
getMCInfo().
process();
02978 photonArray[18] = tempHit->
charge();
02979 photonArray[19] = tempHit->
local().x();
02980 photonArray[20] = tempHit->
local().y();
02981 photonArray[21] = (*clusters)[tempHit->
clusterNumber()]->numberOfPads();
02982 }
02983 tempHit=0;
02984
02985 photonArray[22] = richMcTrack->getGeantMIP().x();
02986 photonArray[23] = richMcTrack->getGeantMIP().y();
02987 photonArray[24] = richMcTrack->getGeantMomentumAtRadiator().x();
02988 photonArray[25] = richMcTrack->getGeantMomentumAtRadiator().y();
02989 photonArray[26] = richMcTrack->getGeantMomentumAtRadiator().z();
02990
02991 photonArray[27] = richMcTrack->getTheta()/degree;
02992 photonArray[28] = richMcTrack->getGeantThetaAtRadiator()/degree;
02993 photonArray[29] = richMcTrack->getPhi()/degree;
02994 photonArray[30] = richMcTrack->getGeantPhiAtRadiator()/degree;
02995 photonArray[31] = richMcTrack->getStMcTrack()->geantId();
02996
02997 photonArray[32] = signalPhoton;
02998 photonArray[33] = mcWave;
02999 photonArray[34] = mcPsi/degree;
03000 photonArray[35] = mcZ;
03001 photonArray[36] = monteCarloRichHit->
getMCInfo().
process();
03002
03003 photonArray[37] = monteCarloRichHit->
local().x();
03004 photonArray[38] = monteCarloRichHit->
local().y();
03005 photonArray[39] = geantRichHit.x();
03006 photonArray[40] = geantRichHit.y();
03007 photonArray[41] = geantParticle->mass();
03008
03009
bool kWriteTheNtuple =
false;
03010
03011 richMcTrack->useTPCInfo();
03012
if (richMcTrack->fastEnough(geantParticle) && richMcTrack->isGood(geantParticle)) {
03013 photonArray[42] = TPC_RingCalc->getConstantAreaAngle();
03014 this->hitFilter(TPC_RingCalc, monteCarloRichHit->
local(),photonArray[43],photonArray[44]);
03015 this->hitFilter(TPC_RingCalc,geantRichHit,photonArray[45],photonArray[46]);
03016
if (fabs(photonArray[44])<5 || fabs(photonArray[46])<5) kWriteTheNtuple=
true;
03017 }
03018
else {
03019 photonArray[42]=defaultValue;
03020 photonArray[43]=defaultValue;
03021 photonArray[44]=defaultValue;
03022 photonArray[45]=defaultValue;
03023 photonArray[46]=defaultValue;
03024 }
03025
03026
03027
03028 richMcTrack->useGeantInfo();
03029
if (richMcTrack->fastEnough(geantParticle) && richMcTrack->isGood(geantParticle)) {
03030 photonArray[47] = GEANT_RingCalc->getConstantAreaAngle();
03031 this->hitFilter(GEANT_RingCalc,monteCarloRichHit->
local(),photonArray[48],photonArray[49]);
03032 this->hitFilter(GEANT_RingCalc,geantRichHit,photonArray[50],photonArray[51]);
03033
if (fabs(photonArray[49])<5 || fabs(photonArray[51])<5) kWriteTheNtuple=
true;
03034 }
03035
else {
03036 photonArray[47]=defaultValue;
03037 photonArray[48]=defaultValue;
03038 photonArray[49]=defaultValue;
03039 photonArray[50]=defaultValue;
03040 photonArray[51]=defaultValue;
03041 }
03042
03043 photonArray[52]=mcTheta/degree;
03044 photonArray[53]=mcPhotTheta/degree;
03045
03046 richMcTrack->useTPCInfo();
03047 geantPhotonNtuple->Fill(photonArray);
03048 }
03049 }
03050
delete TPC_RingCalc;
03051
delete GEANT_RingCalc;
03052 TPC_RingCalc = 0;
03053 GEANT_RingCalc = 0;
03054 }
03055 }
03056 }
03057
#endif
03058
03059
03060
03061
03062
03063
03064
#ifdef myRICH_WITH_MC
03065
void StRichPIDMaker::fillMcTrackNtuple(
const StSPtrVecRichCluster* clusters) {
03066
03067
03068
03069
for (size_t trackIndex=0;trackIndex<mListOfStRichTracks.size();trackIndex++) {
03070 StRichMCTrack* track = dynamic_cast<StRichMCTrack*>(mListOfStRichTracks[trackIndex]);
03071
if (!track) {
03072 cout <<
"trying to send a StTrack to the monte carlo ntuple! " << endl;
03073 abort();
03074 }
03075
03076
03077 cout <<
"geant track ntuple" << endl;
03078
StRichPidTraits* pidTrait = track->getPidTrait();
03079
if (pidTrait) {
03080
03081
StRichPid* pionPid = pidTrait->
getPid(pion);
03082
StRichPid* kaonPid = pidTrait->
getPid(kaon);
03083
StRichPid* protonPid = pidTrait->
getPid(proton);
03084
03085
double PionTotalArea = 0;
03086
double PionConstantArea = 0;
03087
double PionTotalAreaAngle = 0;
03088
double PionConstantAreaAngle = 0;
03089
int PionTotalHits = 0;
03090
int PionConstantHits = 0;
03091
double PionFactor = 0;
03092
03093
if (pionPid) {
03094 PionTotalArea = pionPid->
getTotalArea();
03095 PionConstantArea = pionPid->
getTruncatedArea();
03096 PionTotalAreaAngle = pionPid->
getTotalAzimuth();
03097 PionConstantAreaAngle = pionPid->
getTruncatedAzimuth();
03098 PionTotalHits = pionPid->
getTotalHits();
03099 PionConstantHits = pionPid->
getTruncatedHits();
03100 }
03101
03102
03103
double KaonTotalArea = 0;
03104
double KaonConstantArea = 0;
03105
double KaonTotalAreaAngle = 0;
03106
double KaonConstantAreaAngle = 0;
03107
int KaonTotalHits = 0;
03108
int KaonConstantHits = 0;
03109
double KaonFactor = 0;
03110
03111
if (kaonPid) {
03112 KaonTotalArea = kaonPid->
getTotalArea();
03113 KaonConstantArea = kaonPid->
getTruncatedArea();
03114 KaonTotalAreaAngle = kaonPid->
getTotalAzimuth();
03115 KaonConstantAreaAngle = kaonPid->
getTruncatedAzimuth();
03116 KaonTotalHits = kaonPid->
getTotalHits();
03117 KaonConstantHits = kaonPid->
getTruncatedHits();
03118 }
03119
03120
03121
double ProtonTotalArea = 0;
03122
double ProtonConstantArea = 0;
03123
double ProtonTotalAreaAngle = 0;
03124
double ProtonConstantAreaAngle = 0;
03125
double ProtonFactor = 0;
03126
int ProtonTotalHits = 0;
03127
int ProtonConstantHits = 0;
03128
03129
if (protonPid) {
03130 ProtonTotalArea = protonPid->
getTotalArea();
03131 ProtonConstantArea = protonPid->
getTruncatedArea();
03132 ProtonTotalAreaAngle = protonPid->
getTotalAzimuth();
03133 ProtonConstantAreaAngle = protonPid->
getTruncatedAzimuth();
03134 ProtonTotalHits = protonPid->
getTotalHits();
03135 ProtonConstantHits = protonPid->
getTruncatedHits();
03136 }
03137
03138
03139
03140
03141 StThreeVectorF globalp(track->getStTrack()->geometry()->momentum());
03142
int counter=0;
03143
float defaultValue = -999;
03144
int const entries=88;
03145
float trackArray[entries];
03147
03148 trackArray[counter++] = mEventN;
03149 trackArray[counter++] = mNumberOfPrimaries;
03150 trackArray[counter++] = mNegativePrimaries;
03151 trackArray[counter++] = mVertexPos.z();
03152 trackArray[counter++] = mRichTracks;
03153
03154 trackArray[counter++] = globalp.x();
03155 trackArray[counter++] = globalp.y();
03156 trackArray[counter++] = globalp.z();
03157 trackArray[counter++] = track->getMomentum().x();
03158 trackArray[counter++] = track->getMomentum().y();
03159
03160 trackArray[counter++] = track->getMomentum().z();
03161 trackArray[counter++] = globalp.pseudoRapidity();
03162 trackArray[counter++] = track->getStTrack()->geometry()->charge();
03163
03164
StRichMCHit* tempHit = dynamic_cast<StRichMCHit*>(track->getAssociatedMIP());
03165
if (tempHit) {
03166 trackArray[counter++] = tempHit->
getMCInfo().
id();
03167 trackArray[counter++] = tempHit->
getMCInfo().
process();
03168 trackArray[counter++] = tempHit->
charge();
03169 trackArray[counter++] = tempHit->
local().x();
03170 trackArray[counter++] = tempHit->
local().y();
03171 trackArray[counter++] = (*clusters)[tempHit->
clusterNumber()]->numberOfPads();
03172 }
03173
else {
03174 trackArray[counter++] = defaultValue;
03175 trackArray[counter++] = defaultValue;
03176 trackArray[counter++] = defaultValue;
03177 trackArray[counter++] = defaultValue;
03178 trackArray[counter++] = defaultValue;
03179 trackArray[counter++] = defaultValue;
03180 }
03181 trackArray[counter++] = track->getProjectedMIP().x();
03182
03183
03184 trackArray[counter++] = track->getProjectedMIP().y();
03185
03186 tempHit = track->getGeantRecoMIP();
03187
if (tempHit) {
03188 trackArray[counter++] = tempHit->
getMCInfo().
id();
03189 trackArray[counter++] = tempHit->
getMCInfo().
process();
03190 trackArray[counter++] = tempHit->
charge();
03191 trackArray[counter++] = tempHit->
local().x();
03192 trackArray[counter++] = tempHit->
local().y();
03193 trackArray[counter++] = (*clusters)[tempHit->
clusterNumber()]->numberOfPads();
03194 }
03195
else {
03196 trackArray[counter++] = defaultValue;
03197 trackArray[counter++] = defaultValue;
03198 trackArray[counter++] = defaultValue;
03199 trackArray[counter++] = defaultValue;
03200 trackArray[counter++] = defaultValue;
03201 trackArray[counter++] = defaultValue;
03202 }
03203
03204
03205 trackArray[counter++] = track->getImpactPoint().x();
03206 trackArray[counter++] = track->getImpactPoint().y();
03207
03208
03209
03210
03211
03212
03213
03214
03215 trackArray[counter++] = track->getGeantMomentumAtPadPlane().perp();
03216 trackArray[counter++] = track->getGeantMomentumAtPadPlane().z();
03217
03218
03219
03220 trackArray[counter++] = track->getUnCorrectedMomentum().x();
03221
03222 trackArray[counter++] = track->getUnCorrectedMomentum().y();
03223
03224 trackArray[counter++] = track->getUnCorrectedMomentum().z();
03225 trackArray[counter++] = track->getFirstRow();
03226 trackArray[counter++] = track->getLastRow();
03227 trackArray[counter++] = track->getLastHit().x();
03228 trackArray[counter++] = track->getLastHit().y();
03229
03230 trackArray[counter++] = track->getLastHit().z();
03231 trackArray[counter++] = track->getLastHitDCA();
03232 trackArray[counter++] = track->getPathLength();
03233 trackArray[counter++] = track->getMaxChain();
03234 trackArray[counter++] = track->getMaxGap();
03235
03236 trackArray[counter++] = track->getStTrack()->detectorInfo()->numberOfPoints(kTpcId);
03237 trackArray[counter++] = track->getStTrack()->fitTraits().numberOfFitPoints(kTpcId);
03238 trackArray[counter++] = mMaterialDb->indexOfRefractionOfC6F14At(mMaterialDb->innerWavelength());
03239 trackArray[counter++] = mMaterialDb->indexOfRefractionOfC6F14At(mMaterialDb->outerWavelength());
03240 trackArray[counter++] = track->getGeantMomentumAtRadiator().x();
03241
03242 trackArray[counter++] = track->getGeantMomentumAtRadiator().y();
03243 trackArray[counter++] = track->getGeantMomentumAtRadiator().z();
03244 trackArray[counter++] = track->getGeantImpactPointAtRadiator().x();
03245 trackArray[counter++] = track->getGeantImpactPointAtRadiator().y();
03246 trackArray[counter++] = track->getGeantMIP().x();
03247
03248 trackArray[counter++] = track->getGeantMIP().y();
03249
if (track->getStMcTrack() && track->getStMcTrack()->stopVertex()) {
03250 trackArray[counter++] = track->getStMcTrack()->stopVertex()->position().x();
03251 trackArray[counter++] = track->getStMcTrack()->stopVertex()->position().y();
03252 trackArray[counter++] = track->getStMcTrack()->stopVertex()->position().z();
03253 }
03254
else {
03255 trackArray[counter++] = defaultValue;
03256 trackArray[counter++] = defaultValue;
03257 trackArray[counter++] = defaultValue;
03258 }
03259 trackArray[counter++] = track->getGeantPhotons().size();
03260 trackArray[counter++] = track->getRecoGeantPhotons().size();
03261
03262 trackArray[counter++] = track->getNumberOfGeantHitsInRadiator();
03263 trackArray[counter++] = track->getCommonTpcHits();
03264
if (track->getStMcTrack()) {
03265 trackArray[counter++] = track->getStMcTrack()->momentum().x();
03266 trackArray[counter++] = track->getStMcTrack()->momentum().y();
03267 trackArray[counter++] = track->getStMcTrack()->momentum().z();
03268 }
03269
else {
03270 trackArray[counter++] = defaultValue;
03271 trackArray[counter++] = defaultValue;
03272 trackArray[counter++] = defaultValue;
03273 }
03274
03275
03276
if (track->getStMcTrack()) { trackArray[counter++] = track->getStMcTrack()->geantId();}
03277
else { trackArray[counter++] = defaultValue;}
03278
03279
if (track->getStMcTrack() && track->getStMcTrack()->stopVertex()) {
03280 trackArray[counter++] = track->getStMcTrack()->stopVertex()->geantProcess();}
03281
else { trackArray[counter++] = defaultValue;}
03282
03283 trackArray[counter++] = track->getNumberOfPartners();
03284 trackArray[counter++] = PionFactor;
03285 trackArray[counter++] = PionTotalArea;
03286
03287 trackArray[counter++] = PionConstantArea;
03288 trackArray[counter++] = PionTotalAreaAngle;
03289 trackArray[counter++] = PionConstantAreaAngle;
03290 trackArray[counter++] = PionTotalHits;
03291 trackArray[counter++] = PionConstantHits;
03292
03293 trackArray[counter++] = KaonFactor;
03294 trackArray[counter++] = KaonTotalArea;
03295 trackArray[counter++] = KaonConstantArea;
03296 trackArray[counter++] = KaonTotalAreaAngle;
03297 trackArray[counter++] = KaonConstantAreaAngle;
03298
03299 trackArray[counter++] = KaonTotalHits;
03300 trackArray[counter++] = KaonConstantHits;
03301 trackArray[counter++] = ProtonFactor;
03302 trackArray[counter++] = ProtonTotalArea;
03303 trackArray[counter++] = ProtonConstantArea;
03304
03305 trackArray[counter++] = ProtonTotalAreaAngle;
03306 trackArray[counter++] = ProtonConstantAreaAngle;
03307 trackArray[counter++] = ProtonTotalHits;
03308 trackArray[counter++] = ProtonConstantHits;
03309
03310
if (counter != entries) {cout <<
"StRichPIDMaker::fillMcPidNtuple wrong counter. abort." << endl; abort();}
03311
03312 cout <<
"writing out the ntuple" << endl;
03313 geantTrackNtuple->Fill(trackArray);
03314 }
03315 }
03316 }
03317
#endif
03318
03319
03320
03321
03322
03323
void StRichPIDMaker::initNtuples() {
03324
03325
#ifdef myRICH_WITH_NTUPLE
03326
char finalname[200];
03327 sprintf(finalname,
"%s.root",mySaveDirectory);
03328 file =
new TFile(finalname,
"RECREATE");
03329
03330
#ifdef ROOT_VERSION_CODE < ROOT_VERSION(3,01,00)
03331
file->SetFormat(1);
03332
#endif
03333
03334
03335 file->SetCompressionLevel(9);
03336
03337
#ifdef myPrivateVersion
03338
cout <<
"StRichPIDMaker::initNtuples --> creating mStRichUstTrack. " << endl;
03339 m_Track =
new TrackEntry();
03340 myTree =
new TTree(
"myTree",
"rich pid analysis tree");
03341 myTree->SetAutoSave(10000000);
03342
int bufsize = 2.0*64000;
03343
int split = 1;
03344 myTree->Branch(
"TrackBranch",
"TrackEntry",&m_Track,bufsize,split);
03345
#endif
03346
03347
03348
03349
#ifdef myRICH_WITH_MC
03350
distup =
new TNtuple(
"dist",
"b",
"xi:yi:xo:yo:si:ld:d:oldd:oldsig:oldsi:phx:phy:x:y:px:py:pz:theta:evt:numb:resx:resy:res:ring:cos:d2siline:p:q:vtx:refit:constang:energyloss:runid:amipq:gid");
03351
#else
03352
distup =
new TNtuple(
"dist",
"b",
"xi:yi:xo:yo:si:ld:d:oldd:oldsig:oldsi:phx:phy:x:y:px:py:pz:theta:evt:numb:resx:resy:res:ring:cos:d2siline:p:q:vtx:refit:constang:energyloss:runid:amipq");
03353
#endif
03354
03355
03356
03357
03358
#ifdef myRICH_WITH_MC
03359
geantTrackNtuple =
new TNtuple(
"geantTrackNtuple",
"geant trackwise tuple",
03360
"evtn:nprimaries:nnegprimaries:vz:nrichtracks:globalpx:globalpy:globalpz:localpx:localpy:localpz:eta:q:amipid:amipproc:amipq:amipx:amipy:amipnpads:pmipx:pmipy:gmipid:gmipproc:gmipq:gmipx:gmipy:gmipnpads:radx:rady:gPtp:gPz:olocalpx:olocalpy:olocalpz:firstrow:lastrow:lasthitx:lasthity:lasthitz:lasthitdca:pathlength:maxchain:maxgap:tpchits:tpcfitpoints:innerwave:outerwave:glocalpx:glocalpy:glocalpz:gradx:grady:geantmipx:geantmipy:gstopvertx:gstopverty:gstopvertz:gphots:grecophots:gradhits:gtpccommonhits:gglobalpx:gglobalpy:gglobalpz:gid:gstopproc:gnpartners:pionfactor:piontotalarea:pionconstarea:piontotalangle:pionconstangle:piontotalhits:pionconsthits:kaonfactor:kaontotalarea:kaonconstarea:kaontotalangle:kaonconstangle:kaontotalhits:kaonconsthits:protonfactor:protontotalarea:protonconstarea:protontotalangle:protonconstangle:protontotalhits:protonconsthits");
03361
03362 geantPhotonNtuple =
new TNtuple(
"geantPhotonNtuple",
"geant photon wise tnuple",
"q:localpx:localpy:localpz:radx:rady:gradx:grady:pmipx:pmipy:amipid:amipproc:amipq:amipx:amipy:amipnpads:gamipid:gamipproc:gamipq:gamipx:gamipy:gamipnpads:gmipx:gmipy:glocalpx:glocalpy:glocalpz:theta:gtheta:phi:gphi:gid:signal:gwave:gpsi:gz:gproc:x:y:gx:gy:gmass:constangle:trdist:trang:tgdist:tgang:gconstangle:grdist:grang:ggdist:ggang:gcher:gphottheta");
03363
03364 geantPixelNtuple =
new TNtuple(
"geantPixelNtuple",
"pixels",
"adc:n:gid0:gid1:gid2:gid3:q0:q1:q2:q3:proc0:proc1:proc2:proc3");
03365 geantCloseHitNtuple =
new TNtuple(
"geantHitNtuple",
"pixels",
"p:theta:w1:w2:psi1:psi2:z1:z2:x1:y1:x2:y2:constAngle");
03366
#endif
03367
03368
#endif
03369
}
03370
03371
03372
03373
#ifdef myRICH_WITH_MC
03374
bool StRichPIDMaker::makeTrackAssociations(
StMcEvent* temp_mEvent,
const StSPtrVecRichHit* hits ) {
03375
03376 cout <<
"StRichPIDMaker:makeTrackAssociations()\n";
03377
03378
if (!temp_mEvent || !hits) {
03379 cout <<
"StRichPIDMaker:makeTrackAssociations()\n";
03380 cout <<
"No StMcEvent/rich hits!" << endl;
03381
return false;}
03382
03383
03384 StAssociationMaker* assoc = 0;
03385 assoc = (StAssociationMaker*) GetMaker(
"StAssociationMaker");
03386
if (!assoc) {
03387 cout <<
"StRichPIDMaker:makeTrackAssociation() \n";
03388 cout <<
"No association maker!" << endl;
03389
return false;}
03390
03391 rcTrackMapType* theTrackMap = 0;
03392 theTrackMap = assoc->rcTrackMap();
03393
if (!theTrackMap) {
03394 cout <<
"StRichPIDMaker:makeTrackAssociation() \n";
03395 cout <<
"No track map!" << endl;
03396
return false;}
03397
03398
for (size_t trackIndex=0; trackIndex<mListOfStRichTracks.size(); trackIndex++) {
03399
03400
unsigned int maxCommonTpcHits = 0;
03401
unsigned int numberOfPartners = 0;
03402
03403
StMcTrack* mcPartner = 0;
03404 StRichMCTrack* richMcTrack = dynamic_cast<StRichMCTrack*>(mListOfStRichTracks[trackIndex]);
03405 cout <<
"rich mc track = " << richMcTrack << endl;
03406
if (richMcTrack && richMcTrack->getStTrack() &&
03407 richMcTrack->getStTrack()->node() &&
03408 richMcTrack->getStTrack()->node()->track(global)) {
03409
03410
StGlobalTrack* globaltrack =
03411 dynamic_cast<StGlobalTrack*>(richMcTrack->getStTrack()->node()->track(global));
03412 cout <<
"global track pointer= " << globaltrack << endl;
03413
03414
if (globaltrack) {
03415 pair<rcTrackMapIter,rcTrackMapIter> trackBounds = theTrackMap->equal_range(globaltrack);
03416 cout <<
"about to loop over track bounds " << endl;
03417
03418
for (rcTrackMapIter rcIt = trackBounds.first; rcIt != trackBounds.second; ++rcIt) {
03419 numberOfPartners++;
03420
if ((*rcIt).second->commonTpcHits() > maxCommonTpcHits) {
03421 mcPartner = (*rcIt).second->partnerMcTrack();
03422 maxCommonTpcHits = (*rcIt).second->commonTpcHits();
03423 }
03424 }
03425
03426
03427
03428 St_DataSet* dsGeant = GetDataSet(
"geant");
03429
if(!dsGeant || !dsGeant->GetList()) {
03430 gMessMgr->
Warning() <<
"Could not find dataset geant" << endm;
03431 dsGeant = GetDataSet(
"event/geant/Event");
03432
if(!dsGeant || !dsGeant->GetList()) {
03433 gMessMgr->
Warning() <<
"Could not find dataset event/geant/Event" << endm;
03434
return false;
03435 }
03436 }
03437
03438
03439
03440
03441
03442 St_DataSetIter geantDstI(dsGeant);
03443 St_g2t_track *g2t_track = (St_g2t_track *) geantDstI(
"g2t_track");
03444
03445 richMcTrack->setStMcTrack(mcPartner);
03446 richMcTrack->setGeantPhotons(temp_mEvent);
03447 richMcTrack->setCommonTpcHits(maxCommonTpcHits);
03448 richMcTrack->setNumberOfPartners(numberOfPartners);
03449 richMcTrack->setGeantRecoMIP(hits, temp_mEvent, g2t_track);
03450 richMcTrack->setRecoGeantPhotons(hits,temp_mEvent,g2t_track);
03451 }
03452 }
03453 }
03454
return true;
03455 }
03456
#endif
03457
03458
03459
#ifdef myRICH_WITH_MC
03460
StMcTrack* StRichPIDMaker::getStMcTrack(
StRichMCHit* hit,
StMcEvent* mcevt, St_g2t_track* geantTracks) {
03461
03462
StMcTrack* mcTrack=0;
03463
if (!hit || !mcevt || !geantTracks)
return mcTrack;
03464 g2t_track_st *trackList = geantTracks->GetTable();
03465
03466
unsigned int hitIndex = 0;
03467
if (hit->getMCInfo().process()==ePhoton) hitIndex = hit->getMCInfo().id();
03468
else if (hit->getMCInfo().process()==eCharged) hitIndex = hit->getMCInfo().trackp();
03469
else {
return 0;}
03470
03471
float start=0;
03472
float end = mcevt->
tracks().size()-1;
03473
int index = hitIndex;
03474
int counter=0;
03475
bool searching=
true;
03476
while (searching) {
03477
if (index >= mcevt->
tracks().size()-1)
return 0;
03478
if (trackList[hitIndex].id == mcevt->
tracks()[index]->key()) {
return mcevt->
tracks()[index];}
03479
if (trackList[hitIndex].id > mcevt->
tracks()[index]->key()) {start=index;}
03480
else {end=index;}
03481 index=(end-start)/2 + start;
03482 counter++;
03483
if (counter>mcevt->
tracks().size()-1) searching=
false;
03484 }
03485
return mcTrack;
03486 }
03487
#endif
03488
03489
03490
03491
#ifdef myRICH_WITH_MC
03492
void StRichPIDMaker::getGeantPhotonInfo(StRichMCTrack* richTrack,
StMcTrack* photon,
03493
float& wave,
float& gpsi,
float& z,
float& gtheta,
float& gphottheta) {
03494
03495 wave = -999;
03496 gpsi = -999;
03497 z = -999;
03498 gtheta = -999;
03499 gphottheta = -999;
03500
if (!richTrack || !photon || photon->
geantId()!=50) {
return;}
03501
03502 StRichLocalCoordinate localStartVert(-999,-999,-999);
03503
if (photon->
startVertex()) {
03504 StGlobalCoordinate globalStartVert(photon->
startVertex()->position().x(),
03505 photon->
startVertex()->position().y(),
03506 photon->
startVertex()->position().z());
03507 (*mCoordinateTransformation)(globalStartVert,localStartVert);
03508 }
03509 z = localStartVert.position().z();
03510
03511
03512
03513 StThreeVector<double> globalMomentum(photon->
momentum().x(),
03514 photon->
momentum().y(),
03515 photon->
momentum().z());
03516
03517
03518
03519
if (globalMomentum.mag()==0) {
return;}
03520 globalMomentum.setMag(1.0);
03521 StThreeVector<double> localMomentum;
03522 mMomentumTransformation->localMomentum(globalMomentum,localMomentum);
03523
03524 gphottheta = acos(-localMomentum.z()/localMomentum.mag());
03525
03526 StThreeVectorF trackLocalMomentum = richTrack->getGeantMomentumAtRadiator();
03527
if (trackLocalMomentum.mag() == 0) {
return;}
03528 trackLocalMomentum.setMag(1.0);
03529
03530 StThreeVectorF vect(0.0,0.0,1.0);
03531
double rotationTheta = acos(vect.dot(trackLocalMomentum));
03532
double rotationPhi = trackLocalMomentum.phi();
03533
03534
03535 StThreeVectorF
03536 rotatedTrackMomentum(cos(rotationTheta)*cos(rotationPhi)*trackLocalMomentum.x() +
03537 cos(rotationTheta)*sin(rotationPhi)*trackLocalMomentum.y() -
03538 sin(rotationTheta)*trackLocalMomentum.z(),
03539
03540 -sin(rotationPhi)*trackLocalMomentum.x() +
03541 cos(rotationPhi)*trackLocalMomentum.y(),
03542
03543 cos(rotationPhi)*sin(rotationTheta)*trackLocalMomentum.x() +
03544 sin(rotationPhi)*sin(rotationTheta)*trackLocalMomentum.y() +
03545 cos(rotationTheta)*trackLocalMomentum.z());
03546
03547 StThreeVectorF
03548 photonRotatedMomentum(cos(rotationTheta)*cos(rotationPhi)*localMomentum.x() +
03549 cos(rotationTheta)*sin(rotationPhi)*localMomentum.y() -
03550 sin(rotationTheta)*localMomentum.z(),
03551
03552 -sin(rotationPhi)*localMomentum.x() +
03553 cos(rotationPhi)*localMomentum.y(),
03554
03555 cos(rotationPhi)*sin(rotationTheta)*localMomentum.x() +
03556 sin(rotationPhi)*sin(rotationTheta)*localMomentum.y() +
03557 cos(rotationTheta)*localMomentum.z());
03558
03559 gpsi = atan2( rotatedTrackMomentum.x() - photonRotatedMomentum.x(),
03560 rotatedTrackMomentum.y() - photonRotatedMomentum.y());
03561
03562 gtheta = acos(rotatedTrackMomentum.dot(photonRotatedMomentum));
03563
03564
03565
03566
03567
double constantPhaseDifference = M_PI/2.0;
03568 gpsi = gpsi - constantPhaseDifference;
03569
if (gpsi < -M_PI) {gpsi = gpsi + 2.0*M_PI;}
03570
03571
03572 wave = ( ( (h_Planck/eV)*c_light)/(photon->
energy()/eV) )/nanometer;
03573 }
03574
#endif
03575
03576
03577
#ifdef myRICH_WITH_MC
03578
StThreeVectorF StRichPIDMaker::getTheGeantHitOnPadPlane(
StMcTrack* mcTrack, StThreeVectorF& inputHit) {
03579
03580
03581
double anodeDistanceToPadPlane = mGeometryDb->anodeToPadSpacing();
03582
float defaultValue = -999.9;
03583 StThreeVectorF hit(defaultValue,defaultValue,defaultValue);
03584 StThreeVectorF tempHit(defaultValue,defaultValue,defaultValue);
03585
if (!mcTrack)
return hit;
03586
03587
03588
if (mcTrack->
geantId()==50) {
03589
03590 StGlobalCoordinate testGlobal(mcTrack->
richHits()[0]->position().x(),
03591 mcTrack->
richHits()[0]->position().y(),
03592 mcTrack->
richHits()[0]->position().z());
03593
03594 StRichLocalCoordinate testLocalPoint(0,0,0);
03595 (*mCoordinateTransformation)(testGlobal,testLocalPoint);
03596
03597 hit.setX(testLocalPoint.position().x());
03598 hit.setY(testLocalPoint.position().y());
03599 hit.setZ(testLocalPoint.position().z());
03600 }
03601
03602
03603
else {
03604
for (size_t i=0;i<mcTrack->
richHits().size();i++) {
03605
03606 StGlobalCoordinate testGlobal(mcTrack->
richHits()[i]->position().x(),
03607 mcTrack->
richHits()[i]->position().y(),
03608 mcTrack->
richHits()[i]->position().z());
03609
03610 StRichLocalCoordinate testLocalPoint(0,0,0);
03611 (*mCoordinateTransformation)(testGlobal,testLocalPoint);
03612
03613 tempHit.setX(testLocalPoint.position().x());
03614 tempHit.setY(testLocalPoint.position().y());
03615 tempHit.setZ(testLocalPoint.position().z());
03616
03617
03618
if ( fabs(tempHit.z()) > 0.00 && fabs(tempHit.z()) < 2.0*anodeDistanceToPadPlane ) {
03619
if ( (tempHit-inputHit).perp() < (hit-inputHit).perp() ) {hit = tempHit;}
03620 }
03621 }
03622 }
03623
03624
return hit;
03625 }
03626
03627
#endif
03628
03629
03630
#ifdef RICH_WITH_L3_TRACKS
03631
double StRichPIDMaker::findL3ZVertex(globalTrack * trackVec,
int nTracks){
03632
03633 TH1D temp(
"temp",
"vertex",500,-100,100);
03634
for(
int i = 0;i<nTracks;i++){
03635
double currentVertex;
03636 currentVertex = trackVec[i].z0-trackVec[i].tanl*trackVec[i].r0*cos(trackVec[i].psi-trackVec[i].phi0);
03637 temp.Fill(currentVertex);
03638 }
03639
03640
return temp.GetBinCenter(temp.GetMaximumBin());
03641 }
03642
#endif
03643
03644
03645
03646
03647 ClassImp(StRichPIDMaker)
03648
03649
03650
03651
03652
03653
03654
03655
03656
03657