00001
00002
00003
00004
00005
00006
00008
00009
#include "StSpaceChargeEbyEMaker.h"
00010
#include "StDbUtilities/StMagUtilities.h"
00011
#include "StEventTypes.h"
00012
#include "StMessMgr.h"
00013
#include "StTpcDb/StTpcDb.h"
00014
#include "StTpcDb/StTpcDbMaker.h"
00015
#include "St_db_Maker/St_db_Maker.h"
00016
#include "StTpcHitMoverMaker/StTpcHitMoverMaker.h"
00017
#include "tables/St_spaceChargeCor_Table.h"
00018
#include "StEvent/StDcaGeometry.h"
00019
#include "TUnixTime.h"
00020
00021
#include "TFile.h"
00022
#include "TH2.h"
00023
#include "TH3.h"
00024
#include "TF1.h"
00025
#include "TNtuple.h"
00026
00027
00028
const int SCN = 80;
00029
const float SCL = -0.015;
00030
const float SCH = 0.025;
00031
00032
const int DCN = 125;
00033
const float DCL = -2.5;
00034
const float DCH = 2.5;
00035
00036
const int PHN = 72;
00037
const float PI2 = TMath::TwoPi();
00038
00039
const int EVN = 1024;
00040
00041
const int ZN = 60;
00042
const float ZL = -150.;
00043
const float ZH = 150.;
00044
00045
const int GN = 150;
00046
const float GL = -0.3;
00047
const float GH = 1.2;
00048
const int GZN = 17;
00049
const float GZL = -200.;
00050
const float GZH = 225.;
00051
00052
const float ZGGRID = 208.707;
00053
00054
static TF1 ga1(
"ga1",
"[0]*exp(-0.5*(x-[1])*(x-[1])/([2]*[2]))");
00055
static TF1 ln1(
"ln1",
"[0]+((208.707-abs(x))*[1]/100.0)",-150.,150.);
00056
00057
00058 ClassImp(
StSpaceChargeEbyEMaker)
00059
00060
00061
StSpaceChargeEbyEMaker::
StSpaceChargeEbyEMaker(const
char *name):
StMaker(name),
00062 event(0), Calibmode(kFALSE),
00063 PrePassmode(kFALSE), PrePassdone(kFALSE), QAmode(kFALSE), doNtuple(kFALSE),
00064 doReset(kTRUE), doGaps(kFALSE),
00065 m_ExB(0), tpcDbMaker(0), tpcHitMoverMaker(0),
00066 scehist(0), timehist(0), myhist(0), myhistN(0), myhistP(0),
00067 myhistE(0), myhistW(0), dczhist(0), dcehist(0), dcphist(0),
00068 dcahist(0), dcahistN(0), dcahistP(0), dcahistE(0), dcahistW(0),
00069 gapZhist(0), gapZhistneg(0), gapZhistpos(0),
00070 gapZhisteast(0), gapZhistwest(0), ntup(0) {
00071
00072 HN=96;
00073 MINTRACKS=1500;
00074
00075 SCALER_ERROR = 0.0007;
00076
00077
00078 MAXDIFFE = SCALER_ERROR;
00079
00080 MAXDIFFA = 2*SCALER_ERROR;
00081
00082
00083 runid = 0;
00084 memset(evts,0,HN*
sizeof(
int));
00085 memset(times,0,HN*
sizeof(
int));
00086 memset(evtstbin,0,HN*
sizeof(
float));
00087 evtsnow = 0;
00088
00089 SetMode(0);
00090
00091
00092 schist =
new TH1F(
"SpCh",
"Space Charge",80,SCL,SCH);
00093 schist->SetDirectory(0);
00094
for (
int i=0;i<HN;i++){
00095 schists[i] =
new TH1F(Form(
"SpCh%d",i),
"Space Charge",80,SCL,SCH);
00096 schists[i]->SetDirectory(0);
00097 }
00098 }
00099
00100 StSpaceChargeEbyEMaker::~StSpaceChargeEbyEMaker() {
00101
delete schist;
00102
for (
int i=0;i<HN;i++)
delete schists[i];
00103 }
00104
00105 Int_t
StSpaceChargeEbyEMaker::Finish() {
00106
00107
if (evt > 0) {
00108
if (PrePassmode) {
00109
if (PrePassdone) WriteTableToFile();
00110
else gMessMgr->
Warning(
"StSpaceChargeEbyEMaker: NO SC => NO OUTPUT");
00111 }
00112
if ((!Calibmode)&&(!PrePassdone)) EvalCalib();
00113 WriteQAHists();
00114 }
else {
00115 gMessMgr->
Warning(
"StSpaceChargeEbyEMaker: NO EVENTS => NO OUTPUT");
00116 }
00117
00118
return kStOk;
00119 }
00120
00121 Int_t StSpaceChargeEbyEMaker::Init() {
00122
00123
00124
switch (GetMode()) {
00125
case (1) : DoQAmode();
break;
00126
case (2) : DoPrePassmode();
break;
00127
case (3) : DoPrePassmode(); DoQAmode();
break;
00128
case (4) : DoCalib();
break;
00129
case (10): DoNtuple();
break;
00130
case (11): DoNtuple(); DontReset();
break;
00131
case (12): DoNtuple(); DoQAmode();
break;
00132
case (13): DoNtuple(); DontReset(); DoQAmode();
break;
00133
default : {}
00134 }
00135
00136
if (Calibmode) doReset = kFALSE;
00137
00138 evt=0;
00139 oldevt=1;
00140 lastsc=0.;
00141 curhist=0;
00142 lasttime=0;
00143 did_auto=kTRUE;
00144 InitQAHists();
00145
if (QAmode) gMessMgr->
Info(
"StSpaceChargeEbyEMaker: Initializing");
00146
00147
00148 tpcHitMoverMaker = GetMaker(
"tpc_hit_mover");
00149
00150
00151
if (!tpcHitMoverMaker) {
00152 StMakerIter iter(GetParentChain());
00153
StMaker* mkr;
00154
while ((mkr = iter.NextMaker())) {
00155
if (mkr->IsA() == StTpcDbMaker::Class()) {
00156 tpcDbMaker = mkr;
00157
break;
00158 }
00159 }
00160
if (!tpcDbMaker)
00161 gMessMgr->
Warning(
"StSpaceChargeEbyEMaker: No StTpcDbMaker found.");
00162 }
00163
return StMaker::Init();
00164 }
00165
00166 Int_t
StSpaceChargeEbyEMaker::Make() {
00167
00168
00169
if (PrePassmode && (tabname.Length() == 0)) SetTableName();
00170
00171
00172
if (tpcHitMoverMaker) {
00173 m_ExB = ((
StTpcHitMover*) tpcHitMoverMaker)->getExB();
00174 }
else if (!m_ExB) {
00175 TDataSet *RunLog = GetDataBase(
"RunLog");
00176
if (!RunLog) gMessMgr->
Warning(
"StSpaceChargeEbyEMaker: No RunLog found.");
00177 m_ExB =
new StMagUtilities(
00178 ((StTpcDbMaker*) tpcDbMaker)->tpcDbInterface(),RunLog,(kSpaceChargeR2 | kGridLeak));
00179 }
00180 lastsc = m_ExB->CurrentSpaceChargeR2();
00181
00182
00183 event = (
StEvent*) GetInputDS(
"StEvent");
00184
if (!event) {
00185 gMessMgr->
Warning(
"StSpaceChargeEbyEMaker: no StEvent; skipping event.");
00186
return kStWarn;
00187 }
00188
00189
00190 runinfo = event->
runInfo();
00191
if ((!runinfo) || (runinfo->
magneticField() == 0)) {
00192 gMessMgr->
Error(
"StSpaceChargeEbyEMaker: cannot run due to zero or unknown mag field!");
00193
00194
00195
if ((lastsc != 0) && (runinfo) && (runinfo->
magneticField() == 0))
00196 gMessMgr->
Warning() <<
"BE AWARE THAT A NONZERO VALUE OF SPACECHARGE\n"
00197 <<
" WAS RETURNED BY DB CALL!\n (could be a local DB file or"
00198 <<
" in the actual database)" << endm;
00199
return kStFatal;
00200 }
00201
00202
00203
StPrimaryVertex* pvtx = 0;
float rank = -1e6;
00204
for (
unsigned int l=0; l<event->
numberOfPrimaryVertices(); l++) {
00205
if (!pvtx || event->
primaryVertex(l)->
ranking() > rank) {
00206 pvtx = event->
primaryVertex(l);
00207 rank = pvtx->
ranking();
00208 }
00209 }
00210
if (!pvtx || pvtx->
numberOfDaughters()<10)
return kStOk;
00211 StSPtrVecTrackNode& theNodes = event->
trackNodes();
00212
unsigned int nnodes = theNodes.size();
00213
if (!nnodes)
return kStOk;
00214
00215
00216 evt++;
00217
int thistime = event->
time();
00218
if (lasttime) {
00219 timehist->SetBinContent(evt,thistime-lasttime);
00220 }
else {
00221 runid = event->
runId();
00222 }
00223
if (doReset) {
00224
if (evt>1) curhist = imodHN(curhist+1);
00225 schists[curhist]->Reset();
00226
if (doGaps) {
00227 gapZhist->Reset();
00228 gapZhisteast->Reset();
00229 gapZhistwest->Reset();
00230 gapZhistpos->Reset();
00231 gapZhistneg->Reset();
00232 }
00233 }
else {
00234
00235
if (doNtuple && !Calibmode) ntup->Reset();
00236 }
00237
00238
00239 times[curhist] = thistime;
00240 evts[curhist]=evt;
00241
00242
00243
if (thistime == lasttime) evtsnow++;
00244
else evtsnow = 1;
00245 evtstbin[curhist] = evtsnow;
00246
00247
if (QAmode) {
00248 gMessMgr->
Info()
00249 <<
"used (for this event) SpaceCharge = "
00250 << lastsc <<
" (" << thistime <<
")" << endm;
00251 gMessMgr->
Info()
00252 <<
"zdc west+east = "
00253 << runinfo->
zdcWestRate()+runinfo->
zdcEastRate() << endm;
00254 gMessMgr->
Info()
00255 <<
"zdc coincidence = "
00256 << runinfo->
zdcCoincidenceRate() << endm;
00257 }
00258
00259
00260 runinfo->
setSpaceCharge(lastsc);
00261 runinfo->
setSpaceChargeCorrectionMode(m_ExB->GetSpaceChargeMode());
00262
00263
00264
unsigned int i,j,k;
00265 StThreeVectorD ooo = pvtx->
position();
00266
00267
for (i=0; i<nnodes; i++) {
00268
for (j=0; j<theNodes[i]->entries(global); j++) {
00269
StTrack* tri = theNodes[i]->track(global,j);
00270
if (!tri)
continue;
00271
00272
const StTrackTopologyMap& map = tri->
topologyMap();
00273
00274
if (! map.
hasHitInDetector(kTpcId))
continue;
00275
00276
00277
if (map.
hasHitInDetector(kSvtId))
continue;
00278
if (map.
numberOfHits(kTpcId) < 25)
continue;
00279
StTrackGeometry* triGeom = tri->
geometry();
00280
00281 StThreeVectorF xvec = triGeom->
origin();
00282
if (!(xvec.x() || xvec.y() || xvec.z()))
continue;
00283 StThreeVectorF pvec = triGeom->
momentum();
00284
if (!(pvec.x() || pvec.y()))
continue;
00285
00286
float oldPt = pvec.perp();
00287
if (oldPt < 0.0001)
continue;
00288
00289
int e_or_w = 0;
00290
if (pvec.z() * xvec.z() > 0) e_or_w = ( (xvec.z() > 0) ? 1 : -1 );
00291
00292 StPhysicalHelixD hh = triGeom->
helix();
00293
00294 Float_t eta=pvec.pseudoRapidity();
00295
00296 Float_t DCA3=-999;
00297 Float_t DCA2=-999;
00298
StDcaGeometry* triDcaGeom = ((
StGlobalTrack*) tri)->dcaGeometry();
00299
if (triDcaGeom) {
00300 StPhysicalHelixD dcahh = triDcaGeom->
helix();
00301 DCA3 = dcahh.distance(ooo,kFALSE);
00302 DCA2 = dcahh.geometricSignedDistance(ooo.x(),ooo.y());
00303 }
else {
00304 DCA3 = hh.distance(ooo,kFALSE);
00305 DCA2 = hh.geometricSignedDistance(ooo.x(),ooo.y());
00306 }
00307
if (DCA3 > 4)
continue;
00308 Int_t ch = (
int) triGeom->
charge();
00309
00310 Float_t rerrors[64];
00311 Float_t rphierrors[64];
00312 memset(rerrors,64*
sizeof(Float_t),0);
00313 memset(rphierrors,64*
sizeof(Float_t),0);
00314 StPtrVecHit& hits = tri->
detectorInfo()->
hits();
00315
for (k=0;k<hits.size();k++) {
00316
StHit* hit = hits[k];
00317
unsigned int maskpos = 0;
00318
switch (hit->detector()) {
00319
case (kTpcId) :
00320 maskpos = 7 + ((
StTpcHit*) hit)->padrow();
break;
00321
case (kSvtId) :
00322 maskpos = ((
StSvtHit*) hit)->layer();
break;
00323
case (kSsdId) :
00324 maskpos = 7;
break;
00325
default :
00326 maskpos = 0;
00327 }
00328
if (maskpos) {
00329 StThreeVectorF herrVec = hit->positionError();
00330 Float_t herr = herrVec.perp();
00331 rerrors[maskpos] = herr;
00332 rphierrors[maskpos] = herr;
00333 }
00334 }
00335
00336 Float_t space = 10000.;
00337
if (!(m_ExB->PredictSpaceChargeDistortion(ch,oldPt,ooo.z(),
00338
00339 eta,DCA2,map.
data(0),map.
data(1),rerrors,rphierrors,space)))
continue;
00340
00341 space += lastsc;
00342 schists[curhist]->Fill(space);
00343 FillQAHists(DCA2,space,ch,hh,e_or_w);
00344
00345
00346
if ((doGaps) &&
00347 (map.
hasHitInRow(kTpcId,12))&&(map.
hasHitInRow(kTpcId,14)) &&
00348 (map.
hasHitInRow(kTpcId,11))&&(map.
hasHitInRow(kTpcId,15)) &&
00349 (e_or_w!=0) && (TMath::Abs(ch)==1) && (oldPt>0.3))
00350 FillGapHists(tri,hh,e_or_w,ch);
00351
00352 }
00353 }
00354
00355
00356 ntrks[curhist] = schists[curhist]->Integral();
00357
00358
00359
int result = DecideSpaceCharge(thistime);
00360
00361
if (doGaps) DetermineGaps();
00362
if (doNtuple) {
00363
static float X[37];
00364
static float ntent = 0.0;
00365
static float nttrk = 0.0;
00366
00367
if (ntent == 0.0)
for (i=0; i<37; i++) X[i] = 0.0;
00368 ntent++;
00369
float last_nttrk = nttrk;
00370 nttrk = ntrks[curhist];
00371
float s0 = ( nttrk ? last_nttrk / nttrk : 0 );
00372
float s1 = 1.0 - s0;
00373
00374
if (QAmode) {
00375 gMessMgr->
Info() <<
"reset = " << doReset << endm;
00376 gMessMgr->
Info() <<
"nevts = " << ntent << endm;
00377 gMessMgr->
Info() <<
"ntrks = " << nttrk << endm;
00378 }
00379
00380
float ee;
00381
int fbin = evt + 1 - ((
int) ntent);
00382
00383 X[0] = sc;
00384 X[1] = FindPeak(dcehist->ProjectionY(
"_dy",fbin,evt),ee);
00385 X[2] = s0*X[2] + s1*runinfo->
zdcCoincidenceRate();
00386 X[3] = s0*X[3] + s1*runinfo->
zdcWestRate();
00387 X[4] = s0*X[4] + s1*runinfo->
zdcEastRate();
00388 X[5] = s0*X[5] + s1*runinfo->
bbcCoincidenceRate();
00389 X[6] = s0*X[6] + s1*runinfo->
bbcWestRate();
00390 X[7] = s0*X[7] + s1*runinfo->
bbcEastRate();
00391 X[8] = s0*X[8] + s1*runinfo->
bbcBlueBackgroundRate();
00392 X[9] = s0*X[9] + s1*runinfo->
bbcYellowBackgroundRate();
00393 X[10] = s0*X[10] + s1*runinfo->
initialBeamIntensity(blue);
00394 X[11] = s0*X[11] + s1*runinfo->
initialBeamIntensity(yellow);
00395 X[12] = runinfo->
beamFillNumber(blue);
00396 X[13] = runinfo->
magneticField();
00397 X[14] = event->
runId();
00398 X[15] = event->
id();
00399
00400
00401
if ((QAmode) && (evt <= EVN)) {
00402 X[16] = FindPeak(dcahistN->ProjectionZ(
"_dnz",fbin,evt,1,PHN),ee);
00403 X[17] = FindPeak(dcahistP->ProjectionZ(
"_dpz",fbin,evt,1,PHN),ee);
00404 X[18] = FindPeak(dcahistE->ProjectionZ(
"_dez",fbin,evt,1,PHN),ee);
00405 X[19] = FindPeak(dcahistW->ProjectionZ(
"_dwz",fbin,evt,1,PHN),ee);
00406 }
00407 X[20] = gapZfitslope;
00408 X[21] = gapZfitintercept;
00409 X[22] = gapZdivslope;
00410 X[23] = gapZfitslopeneg;
00411 X[24] = gapZfitinterceptneg;
00412 X[25] = gapZdivslopeneg;
00413 X[26] = gapZfitslopepos;
00414 X[27] = gapZfitinterceptpos;
00415 X[28] = gapZdivslopepos;
00416 X[29] = gapZfitslopeeast;
00417 X[30] = gapZfitintercepteast;
00418 X[31] = gapZdivslopeeast;
00419 X[32] = gapZfitslopewest;
00420 X[33] = gapZfitinterceptwest;
00421 X[34] = gapZdivslopewest;
00422 X[35] = s0*X[35] + s1*runinfo->
spaceCharge();
00423 X[36] = s0*X[36] + s1*((
float) (runinfo->
spaceChargeCorrectionMode()));
00424
00425
00426
if (doReset || !Calibmode) ntup->Fill(X);
00427
00428
if (doReset) {ntent = 0.0; nttrk = 0.0; }
00429
00430 }
00431
00432 lasttime = thistime;
00433
00434
return result;
00435 }
00436
00437 Int_t StSpaceChargeEbyEMaker::DecideSpaceCharge(
int time) {
00438
00439
00440
00441
00442
00443
00444 Bool_t QAout = QAmode || PrePassmode;
00445 Bool_t do_auto = kTRUE;
00446 Bool_t few_stats = kTRUE;
00447 Bool_t large_err = kTRUE;
00448 Bool_t large_dif = kTRUE;
00449
00450
00451
00452
00453
float maxdiff,dif=0;
00454
if (did_auto)
00455 maxdiff = MAXDIFFA;
00456
else
00457 maxdiff = MAXDIFFA - (MAXDIFFA-MAXDIFFE)*oldness(imodHN(curhist-1));
00458
00459
00460
int timedif = time-lasttime;
00461
if (QAout) {
00462 gMessMgr->
Info() <<
"time since last event = "
00463 << timedif << endm;
00464 gMessMgr->
Info() <<
"curhist = "
00465 << curhist << endm;
00466 }
00467
float ntrkstot = 0;
00468 Bool_t decideFromData = ((PrePassmode) || (Calibmode) || (lasttime==0) || (timedif < 30));
00469
if (decideFromData) {
00470
00471
int isc;
00472
static int iscMax = 1;
00473
if (!Calibmode && iscMax<HN) iscMax = curhist+1;
00474
for (isc=0; isc<iscMax; isc++) {
00475
int i = imodHN(curhist-isc);
00476 ntrkstot += ntrks[i] * oldness(i);
00477
if (QAout) {
00478
if (!isc) gMessMgr->
Info(
"Building with: i, ni, oi, nt:");
00479 gMessMgr->
Info() <<
"Building with: " << i <<
", "
00480 << ntrks[i] <<
", " << oldness(i) <<
", " << ntrkstot << endm;
00481 }
00482
00483
00484 few_stats = ntrkstot < MINTRACKS;
00485
if (!few_stats) {
00486 BuildHist(i);
00487 FindSpaceCharge();
00488
if (QAout) gMessMgr->
Info()
00489 <<
"sc = " << sc <<
" +/- " << esc << endm;
00490 large_err = (esc == 0) || (esc > SCALER_ERROR);
00491
if (!large_err) {
00492
if (PrePassmode) { do_auto=kFALSE;
break; }
00493
00494 dif = TMath::Abs(sc-lastsc);
00495 large_dif = dif > maxdiff;
00496
if (!large_dif || Calibmode) {
00497 oldevt = evts[i];
00498 do_auto=kFALSE;
00499
break;
00500 }
00501 }
00502 }
00503
00504
00505
00506
00507 }
00508
if (QAout && (isc == HN)) gMessMgr->
Info()
00509 <<
"STORED DATA EXHAUSTED: "
00510 << HN <<
" events" << endm;
00511 }
00512
00513 did_auto = do_auto;
00514
00515
00516
00517
00518
00519
if (do_auto) {
00520
if (QAout && decideFromData) {
00521
if (few_stats) gMessMgr->
Info()
00522 <<
"(RECENT) STATS TOO FEW: "
00523 << ntrkstot <<
" (" << MINTRACKS <<
")" << endm;
00524
else if (large_err) gMessMgr->
Info()
00525 <<
"FIT ERROR TOO LARGE: "
00526 << esc <<
" (" << SCALER_ERROR <<
")" << endm;
00527
else if (large_dif) gMessMgr->
Info()
00528 <<
"DIFFERENCE TOO LARGE: "
00529 << dif <<
" (" << maxdiff <<
")" << endm;
00530 }
00531 gMessMgr->
Info(
"using auto SpaceCharge");
00532
if (Calibmode) doReset = kFALSE;
00533
else m_ExB->AutoSpaceChargeR2();
00534 }
else {
00535 gMessMgr->
Info() <<
"using SpaceCharge = "
00536 << sc <<
" +/- " << esc <<
" (" << time <<
")" << endm;
00537 scehist->SetBinContent(evt,sc);
00538 scehist->SetBinError(evt,esc);
00539
if (PrePassmode) {
00540 PrePassdone = kTRUE;
00541
return kStStop;
00542 }
00543
if (Calibmode) doReset = kTRUE;
00544
else m_ExB->ManualSpaceChargeR2(sc,m_ExB->CurrentSpaceChargeEWRatio());
00545 }
00546
return kStOk;
00547 }
00548
00549
void StSpaceChargeEbyEMaker::FindSpaceCharge() {
00550 esc = 0.;
00551
double res = FindPeak(schist,esc);
00552
if (res > -500.) sc = res;
00553 }
00554
00555
double StSpaceChargeEbyEMaker::FindPeak(TH1* hist,
float& pkwidth) {
00556
00557 pkwidth = 0.;
00558
if (hist->Integral() < 100.0)
return -998.;
00559
double mn = hist->GetMean();
00560
double rms = TMath::Abs(hist->GetRMS());
00561 mn *= 1.1; rms *= 1.5;
00562
double lr = mn-rms;
00563
double ur = mn+rms;
00564
double pmax = hist->GetMaximum();
00565 ga1.SetParameters(pmax,mn,rms*0.5);
00566 ga1.SetRange(lr,ur);
00567
int fitResult = hist->Fit(&ga1,
"LLR0Q");
00568
if (fitResult != 0)
return -999.;
00569 pkwidth = TMath::Abs(ga1.GetParError(1));
00570
return ga1.GetParameter(1);
00571
00572 }
00573
00574
void StSpaceChargeEbyEMaker::InitQAHists() {
00575
00576 scehist =
new TH1F(
"SpcChgEvt",
"SpaceCharge fit vs. Event",
00577 EVN,0.,EVN);
00578 timehist =
new TH1F(
"EvtTime",
"Event Times",
00579 EVN,0.,EVN);
00580 dcehist =
new TH2F(
"DcaEve",
"psDCA vs. Event",
00581 EVN,0.,EVN,DCN,DCL,DCH);
00582 dcphist =
new TH3F(
"DcaPhi",
"psDCA vs. Phi",
00583 PHN,0,PI2,DCN,DCL,DCH,(QAmode ? 3 : 1),-1.5,1.5);
00584
00585 AddHist(scehist);
00586 AddHist(timehist);
00587 AddHist(dcehist);
00588 AddHist(dcphist);
00589
00590
if (QAmode) {
00591 myhist =
new TH3F(
"SpcEvt",
"SpaceCharge vs. Phi vs. Event",
00592 EVN,0.,EVN,PHN,0,PI2,SCN,SCL,SCH);
00593 dcahist =
new TH3F(
"DcaEvt",
"psDCA vs. Phi vs. Event",
00594 EVN,0.,EVN,PHN,0,PI2,DCN,DCL,DCH);
00595 dczhist =
new TH2F(
"DcaZ",
"psDCA vs. Z",
00596
00597 ZN,ZL,ZH,DCN,DCL,DCH);
00598 myhistN =
new TH3F(
"SpcEvtN",
"SpaceCharge vs. Phi vs. Event Neg",
00599 EVN,0.,EVN,PHN,0,PI2,SCN,SCL,SCH);
00600 myhistP =
new TH3F(
"SpcEvtP",
"SpaceCharge vs. Phi vs. Event Pos",
00601 EVN,0.,EVN,PHN,0,PI2,SCN,SCL,SCH);
00602 myhistE =
new TH3F(
"SpcEvtE",
"SpaceCharge vs. Phi vs. Event East",
00603 EVN,0.,EVN,PHN,0,PI2,SCN,SCL,SCH);
00604 myhistW =
new TH3F(
"SpcEvtW",
"SpaceCharge vs. Phi vs. Event West",
00605 EVN,0.,EVN,PHN,0,PI2,SCN,SCL,SCH);
00606 dcahistN =
new TH3F(
"DcaEvtN",
"psDCA vs. Phi vs. Event Neg",
00607 EVN,0.,EVN,PHN,0,PI2,DCN,DCL,DCH);
00608 dcahistP =
new TH3F(
"DcaEvtP",
"psDCA vs. Phi vs. Event Pos",
00609 EVN,0.,EVN,PHN,0,PI2,DCN,DCL,DCH);
00610 dcahistE =
new TH3F(
"DcaEvtE",
"psDCA vs. Phi vs. Event East",
00611 EVN,0.,EVN,PHN,0,PI2,DCN,DCL,DCH);
00612 dcahistW =
new TH3F(
"DcaEvtW",
"psDCA vs. Phi vs. Event West",
00613 EVN,0.,EVN,PHN,0,PI2,DCN,DCL,DCH);
00614 AddHist(myhist);
00615 AddHist(dcahist);
00616 AddHist(dczhist);
00617 AddHist(myhistN);
00618 AddHist(myhistP);
00619 AddHist(myhistE);
00620 AddHist(myhistW);
00621 AddHist(dcahistN);
00622 AddHist(dcahistP);
00623 AddHist(dcahistE);
00624 AddHist(dcahistW);
00625 }
00626
00627
if (doNtuple) ntup =
new TNtuple(
"SC",
"Space Charge",
00628
"sc:dca:zdcx:zdcw:zdce:bbcx:bbcw:bbce:bbcbb:bbcyb:intb:inty:fill:mag:run:event:dcan:dcap:dcae:dcaw:gapf:gapi:gapd:gapfn:gapin:gapdn:gapfp:gapip:gapdp:gapfe:gapie:gapde:gapfw:gapiw:gapdw:usc:uscmode");
00629
00630
00631
if (doGaps) {
00632 gapZhist =
new TH2F(
"Gaps",
"Gaps",GN,GL,GH,GZN,GZL,GZH);
00633 gapZhistneg =
new TH2F(
"Gapsneg",
"Gaps Neg",GN,GL,GH,GZN,GZL,GZH);
00634 gapZhistpos =
new TH2F(
"Gapspos",
"Gaps Pos",GN,GL,GH,GZN,GZL,GZH);
00635 gapZhisteast =
new TH2F(
"Gapseast",
"Gaps East",GN,GL,GH,GZN,GZL,GZH);
00636 gapZhistwest =
new TH2F(
"Gapswest",
"Gaps West",GN,GL,GH,GZN,GZL,GZH);
00637 }
00638
00639 }
00640
00641
void StSpaceChargeEbyEMaker::WriteQAHists() {
00642
00643
00644
if (!(QAmode || doNtuple || doGaps))
return;
00645
00646
if (runid == 0) {
00647 gMessMgr->
Error(
"StSpaceChargeEbyEMaker: No runid => No output");
00648
return;
00649 }
00650
00651
const char* f1 =
GetName();
00652 runid -= 1000000*(runid/1000000);
00653 runid *= 100;
00654 TString fname =
"./hists";
00655
if (PrePassmode) fname.Append(
"Pre");
00656 gSystem->cd(fname.Data());
00657
while (f1) {
00658 fname = Form(
"Hist%d.root",runid);
00659 f1 = gSystem->Which(
".",fname.Data());
00660 runid++;
00661 }
00662
00663 TFile ff(fname.Data(),
"RECREATE");
00664
if (QAmode) {
00665 myhist->Write();
00666 dcehist->Write();
00667 dcphist->Write();
00668 dcahist->Write();
00669 dczhist->Write();
00670 myhistN->Write();
00671 dcahistN->Write();
00672 myhistP->Write();
00673 dcahistP->Write();
00674 myhistE->Write();
00675 dcahistE->Write();
00676 myhistW->Write();
00677 dcahistW->Write();
00678 scehist->Write();
00679 timehist->Write();
00680 }
00681
if (doGaps) {
00682 gapZhist->Write();
00683 gapZhistneg->Write();
00684 gapZhistpos->Write();
00685 gapZhisteast->Write();
00686 gapZhistwest->Write();
00687 }
00688
if (doNtuple) ntup->Write();
00689 ff.Close();
00690
00691 gMessMgr->
Info() <<
"QA hists file: " << fname.Data() << endm;
00692
00693 gSystem->cd(
"..");
00694
00695 }
00696
00697
void StSpaceChargeEbyEMaker::FillQAHists(
float DCA,
float space,
int ch,
00698 StPhysicalHelixD& hh,
int e_or_w) {
00699
00700 pairD pls = hh.pathLength(97.0);
00701
double pl = pls.first;
00702
if (TMath::Abs(pls.second) < TMath::Abs(pls.first)) pl = pls.second;
00703 StThreeVectorD hh_at_pl = hh.at(pl);
00704
float Phi = hh_at_pl.phi();
00705
while (Phi < 0) Phi += PI2;
00706
while (Phi >= TMath::TwoPi()) Phi -= PI2;
00707
00708
00709
00710
00711
float evtn = ((
float) evt) - 0.5;
00712 dcehist->Fill(evtn,DCA);
00713 dcphist->Fill(Phi,DCA,(
float) e_or_w);
00714
00715
if (QAmode) {
00716 myhist->Fill(evtn,Phi,space);
00717 dcahist->Fill(evtn,Phi,DCA);
00718
if (ch > 0) {
00719 myhistP->Fill(evtn,Phi,space);
00720 dcahistP->Fill(evtn,Phi,DCA);
00721 }
else {
00722 myhistN->Fill(evtn,Phi,space);
00723 dcahistN->Fill(evtn,Phi,DCA);
00724 }
00725
if (e_or_w > 0) {
00726 myhistW->Fill(evtn,Phi,space);
00727 dcahistW->Fill(evtn,Phi,DCA);
00728 }
else if (e_or_w < 0) {
00729 myhistE->Fill(evtn,Phi,space);
00730 dcahistE->Fill(evtn,Phi,DCA);
00731 }
00732
if ((e_or_w != 0) && (TMath::Abs(hh.dipAngle()) < 0.05)) dczhist->Fill(hh_at_pl.z(),DCA);
00733 }
00734 }
00735
00736
int StSpaceChargeEbyEMaker::imodHN(
int i) {
00737
00738
return ( i >= HN ? imodHN(i-HN) : (i < 0 ? imodHN(i+HN) : i) );
00739 }
00740
00741
float StSpaceChargeEbyEMaker::oldness(
int i,
int j) {
00742
00743
00744
static float decay_const = -0.12;
00745
00746
float s = 1.0;
00747
if (!PrePassmode) {
00748
if (j<0) j = curhist;
00749
00750
00751
00752
00753
00754
int k = i;
00755
while (k!=j) {
00756 k = imodHN(k+1);
00757
if (times[k] != times[i]) { k = imodHN(k-1);
break; }
00758 }
00759
00760
float time_factor = (times[j]-times[i]) + (1.-(evtstbin[i]/evtstbin[k]));
00761
00762 s = exp( decay_const * time_factor );
00763 }
00764
return s;
00765 }
00766
00767
void StSpaceChargeEbyEMaker::BuildHist(
int i) {
00768
00769 schist->Reset();
00770
int isc = curhist;
00771 schist->Add(schists[isc],1.0);
00772
while (isc != i) {
00773 isc = imodHN(isc-1);
00774 schist->Add(schists[isc],oldness(isc));
00775 }
00776 }
00777
00778
void StSpaceChargeEbyEMaker::SetTableName() {
00779
00780
00781 TUnixTime ux(GetDateTime(),1);
00782 ux+=-10;
00783
int date,time;
00784 ux.GetGTime(date,time);
00785 gMessMgr->
Info() <<
"first event date = " << date << endm;
00786 gMessMgr->
Info() <<
"first event time = " << time << endm;
00787 tabname = Form(
"./StarDb/Calibrations/rich/spaceChargeCorR2.%08d.%06d.C",date,time);
00788 }
00789
00790
void StSpaceChargeEbyEMaker::WriteTableToFile(){
00791 gMessMgr->
Info() <<
"Writing new table to:\n "
00792 << tabname.Data() << endm;
00793 TString dirname = gSystem->DirName(tabname.Data());
00794 TString estr = dirname;
00795 estr.Prepend(
"mkdir -p ");
00796 gSystem->Exec(estr.Data());
00797
if (gSystem->OpenDirectory(dirname.Data())==0) {
00798
if (gSystem->mkdir(dirname.Data())) {
00799 gMessMgr->
Warning() <<
"Directory creation failed for:\n " << dirname
00800 <<
"\n Putting table file in current directory" << endm;
00801 tabname.Remove(0,tabname.Last(
'/')).Prepend(
".");
00802 }
00803 }
00804 ofstream *out =
new ofstream(tabname.Data());
00805 SCTable()->SavePrimitive(*out,
"");
00806
return;
00807 }
00808
00809 St_spaceChargeCor* StSpaceChargeEbyEMaker::SCTable() {
00810 St_spaceChargeCor* table =
new St_spaceChargeCor(
"spaceChargeCorR2",1);
00811 spaceChargeCor_st* row = table->GetTable();
00812 row->fullFieldB = sc;
00813 row->halfFieldB = sc;
00814 row->zeroField = (
float) evt;
00815 row->halfFieldA = sc;
00816 row->fullFieldA = sc;
00817 row->satRate = 1.0;
00818 row->factor = 1.0;
00819 row->detector = 3;
00820 row->offset = 0;
00821 row->ewratio = m_ExB->CurrentSpaceChargeEWRatio();
00822 table->SetNRows(1);
00823
return table;
00824 }
00825
00826
float StSpaceChargeEbyEMaker::FakeAutoSpaceCharge() {
00827
00828
float zdcsum = runinfo->
zdcWestRate()+runinfo->
zdcEastRate();
00829
float sc = 6e-8 * zdcsum;
00830
00831
return sc;
00832 }
00833
00834
void StSpaceChargeEbyEMaker::FillGapHists(
StTrack* tri, StPhysicalHelixD& hh,
00835
int e_or_w,
int ch) {
00836
float fsign = ( event->
runInfo()->
magneticField() < 0 ? -1 : 1 );
00837 StPtrVecHit hts = tri->
detectorInfo()->
hits(kTpcId);
00838
float gap = 0.;
float zgap = 0.;
int ct=0;
00839
for (UInt_t ht=0; ht<hts.size(); ht++) {
00840
StTpcHit* hit = (
StTpcHit*) hts[ht];
00841 UInt_t prow = hit->padrow();
00842
if ((prow != 12) && (prow != 14))
continue;
00843
float gsign = ( prow == 14 ? -1 : 1 );
00844
const StThreeVectorF& hp = hit->position();
00845
00846
00847
float hphi = hp.phi() + TMath::TwoPi();
00848
while (hphi > TMath::Pi()/12.) hphi -= TMath::Pi()/6.;
00849
if (TMath::Abs(hphi) > 0.75*TMath::Pi()/12.)
break;
00850
00851 gap += fsign * gsign * hh.geometricSignedDistance(hp.x(),hp.y());
00852 zgap += (hp.z() / 12.795) * ( prow == 14 ? 7.4 : 5.395 );
00853 ct++;
00854 }
00855
00856
float abs_zgap = TMath::Abs(zgap);
00857
if ((ct==2) && (abs_zgap<200.0) && (abs_zgap>10.0)) {
00858 gapZhist->Fill(gap,zgap);
00859
if (e_or_w==1) gapZhistwest->Fill(gap,zgap);
00860
else gapZhisteast->Fill(gap,zgap);
00861
if (ch==1) gapZhistpos->Fill(gap,zgap);
00862
else gapZhistneg->Fill(gap,zgap);
00863
if (abs_zgap<150 && abs_zgap>25) {
00864
00865
float gap_scaled = (gap * 100.0) / (ZGGRID - abs_zgap);
00866
00867
float z_beyond = ZGGRID+1.0;
00868 gapZhist->Fill(gap_scaled,z_beyond);
00869
if (e_or_w==1) gapZhistwest->Fill(gap_scaled,z_beyond);
00870
else gapZhisteast->Fill(gap_scaled,z_beyond);
00871
if (ch==1) gapZhistpos->Fill(gap_scaled,z_beyond);
00872
else gapZhistneg->Fill(gap_scaled,z_beyond);
00873 }
00874 }
00875 }
00876
00877
void StSpaceChargeEbyEMaker::DetermineGaps() {
00878 DetermineGapHelper(gapZhistneg,gapZfitslopeneg,gapZfitinterceptneg,gapZdivslopeneg);
00879 DetermineGapHelper(gapZhistpos,gapZfitslopepos,gapZfitinterceptpos,gapZdivslopepos);
00880 DetermineGapHelper(gapZhisteast,gapZfitslopeeast,gapZfitintercepteast,gapZdivslopeeast);
00881 DetermineGapHelper(gapZhistwest,gapZfitslopewest,gapZfitinterceptwest,gapZdivslopewest);
00882 DetermineGapHelper(gapZhist,gapZfitslope,gapZfitintercept,gapZdivslope);
00883 }
00884
00885
void StSpaceChargeEbyEMaker::DetermineGapHelper(TH2F* hh,
00886
float& fitslope,
float& fitintercept,
float& divslope) {
00887
00888 ga1.SetParameters(hh->GetEntries()/(16.*2.*10.),0.,0.1);
00889 hh->FitSlicesX(&ga1,1,0,20,
"LL0Q");
00890
const char* hn = hh->GetName();
00891 TH1D* GapsChi2 = (TH1D*) gDirectory->Get(Form(
"%s_chi2",hn));
00892 TH1D* GapsAmp = (TH1D*) gDirectory->Get(Form(
"%s_0",hn));
00893 TH1D* GapsMean = (TH1D*) gDirectory->Get(Form(
"%s_1",hn));
00894 TH1D* GapsRMS = (TH1D*) gDirectory->Get(Form(
"%s_2",hn));
00895
00896 divslope = GapsMean->GetBinContent(GZN);
00897 egapZdivslope = TMath::Abs(GapsMean->GetBinError(GZN));
00898
00899
00900
00901 GapsMean->SetBinContent(8,0); GapsMean->SetBinError(8,0);
00902 GapsMean->SetBinContent(9,0); GapsMean->SetBinError(9,0);
00903
00904 GapsMean->Fit(&ln1,
"R0Q");
00905 fitslope = ln1.GetParameter(1);
00906 egapZfitslope = TMath::Abs(ln1.GetParError(1));
00907 fitintercept = ln1.GetParameter(0);
00908 egapZfitintercept = TMath::Abs(ln1.GetParError(0));
00909
00910
delete GapsChi2;
00911
delete GapsAmp;
00912
delete GapsMean;
00913
delete GapsRMS;
00914 }
00915
00916
#include "TPad.h"
00917
float StSpaceChargeEbyEMaker::EvalCalib(TDirectory* hdir) {
00918
00919
if (hdir) {
00920 dcehist = (TH2F*) (hdir->Get(
"DcaEve"));
00921 timehist = (TH1F*) (hdir->Get(
"EvtTime"));
00922 scehist = (TH1F*) (hdir->Get(
"SpcChgEvt"));
00923
if (!(dcehist && timehist && scehist)) {
00924 LOG_ERROR <<
"Problems finding SC histograms" << endm;
00925
return 999.;
00926 }
00927 }
00928
00929 TH1D* dcaproj = dcehist->ProjectionY();
00930
00931
00932 ga1.SetParameters(1.,0.,1.);
00933 dcaproj->Fit(
"ga1",
"Q");
00934
float hm = ga1.GetParameter(1);
00935
float hw = TMath::Abs(ga1.GetParameter(2));
00936
float hd = 0.6*hw;
00937 ga1.SetRange(hm-hd,hm+hd);
00938 dcaproj->Fit(
"ga1",
"RQ");
00939
float gm = ga1.GetParameter(1);
00940
float gw = TMath::Abs(ga1.GetParameter(2));
00941
float gm1 = gm;
00942
float gw1 = gw;
00943
00944
00945 ga1.SetRange(gm-0.9*gw,gm+0.9*gw);
00946 dcaproj->Fit(
"ga1",
"RQ");
00947 gm = ga1.GetParameter(1);
00948 gw = TMath::Abs(ga1.GetParameter(2));
00949 ga1.SetRange(gm-0.8*gw,gm+0.8*gw);
00950 dcaproj->Fit(
"ga1",
"RQ");
00951 gm = ga1.GetParameter(1);
00952 gw = TMath::Abs(ga1.GetParameter(2));
00953 ga1.SetRange(gm-0.7*gw,gm+0.7*gw);
00954 dcaproj->Fit(
"ga1",
"RQ");
00955 gm = ga1.GetParameter(1);
00956 gw = TMath::Abs(ga1.GetParameter(2));
00957
float gme = TMath::Abs(ga1.GetParError(1));
00958
float gwe = TMath::Abs(ga1.GetParError(2));
00959
00960
00961 scehist->Fit(
"pol0",
"Q");
00962 TF1* pl0 = scehist->GetFunction(
"pol0");
00963
float pm = pl0->GetParameter(0);
00964
float pw = pl0->GetParError(0);
00965
00966
00967
float spc = (
float) (scehist->GetEntries());
00968
float dcc = (
float) (dcehist->GetEntries());
00969
float evc = (
float) (timehist->GetEntries());
00970 timehist->GetXaxis()->SetRange(1,(
int) evc);
00971 timehist->Fit(
"pol0",
"LQ");
00972 pl0 = timehist->GetFunction(
"pol0");
00973
float epsec = pl0->GetParameter(0);
00974
00975
00976
float wid = TMath::Min(10.,TMath::Log10(gw1*gw1+gw*gw));
00977
float frac = spc/evc;
00978
00979
float code=0;
00980
if (frac<0.2) code = 1. + frac;
00981
else if (wid>0) code = 2. + 0.1*wid;
00982
00983 LOG_INFO << Form(
"SCeval: %f %f %f %f %f %f %f %f %f %f %f %f %f %f\n",
00984 hm,hw,gm,gw,pm,pw,gm1,gw1,spc,dcc,evc,epsec,gme,gwe) << endm;
00985
00986
if (code>0) {
00987 LOG_ERROR <<
"CheckFail: Break of SpaceCharge performance! code = " << code << endm;
00988 }
00989
00990
return code;
00991 }
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061