StPass0CalibMaker/StSpaceChargeEbyEMaker.cxx

00001 00002 // // 00003 // StSpaceChargeEbyEMaker performs event-by-event determination // 00004 // of the space charge correction for tracks, and sets it for // 00005 // the next event. // 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 // Histogram ranges: 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 //static TF1 ln1("ln1","[0]+((350.0-abs(x))*[1]/100.0)",-150.,150.); 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; // max events used, cannot exceed 96 used in header file 00073 MINTRACKS=1500; 00074 //SCALER_ERROR = 0.0006; // by eye from hist: SCvsZDCEpW.gif (liberal) 00075 SCALER_ERROR = 0.0007; // by RMS from hist: SCvsZDCX.gif (liberal) 00076 00077 // MAXDIFFE is maximum different in sc from last ebye sc 00078 MAXDIFFE = SCALER_ERROR; 00079 // MAXDIFFA is maximum different in sc from last scaler sc 00080 MAXDIFFA = 2*SCALER_ERROR; // should be about equal to SCALER_ERROR, no? 00081 // Present uncetainties with scalers demands greater tolerance 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); // default is mode 0 (no QA, no PrePass) 00090 //DoQAmode(); // For testing 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 // Use mode to set switches: 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 // Find StTpcHitMoverMaker 00148 tpcHitMoverMaker = GetMaker("tpc_hit_mover"); 00149 00150 // Find StTpcDbMaker if no StTpcHitMoverMaker 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 // On very first event 00169 if (PrePassmode && (tabname.Length() == 0)) SetTableName(); 00170 00171 // Get instance of StMagUtilities 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 // Get StEvent and related info, determine if things are OK 00183 event = (StEvent*) GetInputDS("StEvent"); 00184 if (!event) { 00185 gMessMgr->Warning("StSpaceChargeEbyEMaker: no StEvent; skipping event."); 00186 return kStWarn; 00187 } 00188 // Get runinfo, determine if the magnetic field is nonzero 00189 // EbyE maker not currently able to handle zero B field 00190 runinfo = event->runInfo(); 00191 if ((!runinfo) || (runinfo->magneticField() == 0)) { 00192 gMessMgr->Error("StSpaceChargeEbyEMaker: cannot run due to zero or unknown mag field!"); 00193 // Look for any errant zero field SC values as a warning 00194 // for processing even without EbyE 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 // Select the highest ranked vertex 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 // Store and setup event-wise info 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 // Do not reset ntuple in calib mode 00235 if (doNtuple && !Calibmode) ntup->Reset(); 00236 } 00237 00238 // Keep time and event number 00239 times[curhist] = thistime; 00240 evts[curhist]=evt; 00241 00242 // Keep track of # of events in the same time bin 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 // Fill the StEvent information for the SpaceCharge used in this event 00260 runinfo->setSpaceCharge(lastsc); 00261 runinfo->setSpaceChargeCorrectionMode(m_ExB->GetSpaceChargeMode()); 00262 00263 // Track loop 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 //if (! map.trackTpcOnly()) continue; 00274 if (! map.hasHitInDetector(kTpcId)) continue; 00275 // Multiple silicon hits destroy sDCA <-> SpaceCharge correlation, 00276 // and single hit in SVT is unreliable. Only good config is NO SVT! 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; // east is -1, west is +1 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 //Float_t DCA=hh.geometricSignedDistance(0,0); // for testing only 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; // cut out pileup tracks! 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 // eta,DCA2,map.data(0),map.data(1),space))) continue; 00339 eta,DCA2,map.data(0),map.data(1),rerrors,rphierrors,space))) continue; 00340 00341 space += lastsc; // Assumes additive linearity of space charge! 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 } // loop over j tracks 00353 } // loop over i Nodes 00354 00355 00356 ntrks[curhist] = schists[curhist]->Integral(); 00357 00358 // Wrap it up and make a decision 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++; // # entries since last reset, including this one 00369 float last_nttrk = nttrk; 00370 nttrk = ntrks[curhist]; // # tracks since last reset, including these 00371 float s0 = ( nttrk ? last_nttrk / nttrk : 0 ); 00372 float s1 = 1.0 - s0; // fraction of tracks from current event 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); // west-bound 00394 X[11] = s0*X[11] + s1*runinfo->initialBeamIntensity(yellow); // east-bound 00395 X[12] = runinfo->beamFillNumber(blue); 00396 X[13] = runinfo->magneticField(); 00397 X[14] = event->runId(); 00398 X[15] = event->id(); 00399 //X[16] = sceast; 00400 //X[17] = scwest; 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 // In calib mode, only fill when doReset (we found an sc) 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 // curhist has only this event 00440 // curhist-1 has past two events... 00441 // curhist-x has past (x+1) events 00442 // curhist-(HN-1) == curhist+1 has past HN events 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 // Cuts on difference from previous sc measure: 00451 // If last event was auto, use MAXDIFFA, else use between MAXDIFFE & MAXDIFFA 00452 // scaled by oldness of previous sc measure (curhist-1) 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 // More than 30 seconds since last used event? Forget it... 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; // running sum using oldness scale factor 00468 Bool_t decideFromData = ((PrePassmode) || (Calibmode) || (lasttime==0) || (timedif < 30)); 00469 if (decideFromData) { 00470 00471 int isc; 00472 static int iscMax = 1; // use only one hist for calib mode, and... 00473 if (!Calibmode && iscMax<HN) iscMax = curhist+1; // don't use uninitialized 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 // Too little data collected? Keep trying... 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 // otherwise, check for big jumps 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 // shouldn't need to go past oldest event previously used? 00505 // tough to know - allow for now as of 11 Jan 2008 00506 // if (evts[i] <= oldevt) break; 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 // In normal mode, do_auto decides whether to use automatic SC from DB 00516 // In PrePass mode, do_auto decides when we're ready to stop 00517 // In Calib mode, do_auto decides when to save entries and reset 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; // We're happy! Let's stop! 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 //80,-200,200,250,-5.0,5.0); 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 //"sc:dca:zdcx:zdcw:zdce:bbcx:bbcw:bbce:bbcbb:bbcyb:intb:inty:fill:mag:run:event:sce:scw:dcae:dcaw:gapf:gapd:gapfn:gapdn:gapfp:gapdp:gapfe:gapde:gapfw:gapdw:usc:uscmode"); 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 // Only if QAmode or doNtuple or doGaps 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); // Remove the year, optional 00653 runid *= 100; // limits one run to 100 files! 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 // Find a "Phi" for the track 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 // To pile all sectors atop each other: 00709 // while (Phi >= TMath::Pi()/6.) Phi -= TMath::Pi()/6.; 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 // Keep index in bounds of circular queue 00738 return ( i >= HN ? imodHN(i-HN) : (i < 0 ? imodHN(i+HN) : i) ); 00739 } 00740 //_____________________________________________________________________________ 00741 float StSpaceChargeEbyEMaker::oldness(int i, int j) { 00742 // Deterime how to treat relative "age" of event 00743 // In PrePassmode, earliest events are most important! 00744 static float decay_const = -0.12; 00745 //static float decay_const = -0.15; 00746 float s = 1.0; 00747 if (!PrePassmode) { // Weight newest the most (or evenly for PrePass) 00748 if (j<0) j = curhist; 00749 00750 // Weight in sub-second intervals by # of events because 00751 // times have only 1 second granularity (best we can do). 00752 // Method assumes time-ordering of events, which is violated 00753 // perhaps only occasionally from DAQ. 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 // # seconds + fraction of a second: 00760 float time_factor = (times[j]-times[i]) + (1.-(evtstbin[i]/evtstbin[k])); 00761 //float time_factor = (times[j]-times[i]); 00762 s = exp( decay_const * time_factor ); 00763 } 00764 return s; 00765 } 00766 //_____________________________________________________________________________ 00767 void StSpaceChargeEbyEMaker::BuildHist(int i) { 00768 // Build up one histogram from several events 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 // Problem caused if first event comes later in time than other events. 00780 // Solution: subtract 10 seconds... 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 // Use this to mimic what is done with the scalers, using your own code 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 // Avoid sector edges 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 ); // ~z at gap 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) { // Restrict the Z range further 00864 // normalize at z=100cm from ggrid 00865 float gap_scaled = (gap * 100.0) / (ZGGRID - abs_zgap); 00866 //float gap_scaled = (gap * 100.0) / (350.0 - abs_zgap); 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 // Fit only from |Z| = 25-150cm 00900 // Zero bins -25 thru 25cm (depends upon GZN,GZL,GZH definitions) 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 // Initial fits to DCA distribution 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 // Iterate fit to get best answer 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 // Average SC 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 // Other counts 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); // events per second 00974 00975 // Quality measures 00976 float wid = TMath::Min(10.,TMath::Log10(gw1*gw1+gw*gw)); 00977 float frac = spc/evc; // fraction of events for which SC was found 00978 00979 float code=0; 00980 if (frac<0.2) code = 1. + frac; // code = 1.x 00981 else if (wid>0) code = 2. + 0.1*wid; // code = 2.x 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 // $Id: StSpaceChargeEbyEMaker.cxx,v 1.22 2008/07/24 19:17:55 genevb Exp $ 00994 // $Log: StSpaceChargeEbyEMaker.cxx,v $ 00995 // Revision 1.22 2008/07/24 19:17:55 genevb 00996 // SpaceChargeEWRatio must be written to prepass output table 00997 // 00998 // Revision 1.21 2008/07/21 21:17:10 genevb 00999 // No call to EvalCalib() if Prepass runs successfully 01000 // 01001 // Revision 1.20 2008/07/17 23:35:33 jeromel 01002 // Small format change 01003 // 01004 // Revision 1.19 2008/07/16 03:42:15 genevb 01005 // Use CheckFail in failed performance check error message 01006 // 01007 // Revision 1.18 2008/07/15 22:30:38 genevb 01008 // Added evaluation of calibration performance 01009 // 01010 // Revision 1.17 2008/04/30 14:52:15 genevb 01011 // Reduce pileup contributions 01012 // 01013 // Revision 1.16 2008/01/14 19:22:49 genevb 01014 // Fine tuning of parameters, removal of excess text in messages 01015 // 01016 // Revision 1.15 2007/01/25 19:04:04 perev 01017 // GMT fix 01018 // 01019 // Revision 1.14 2007/01/24 21:42:22 perev 01020 // GMT conversion fixed 01021 // 01022 // Revision 1.13 2006/12/16 01:00:58 genevb 01023 // Better handling of zero magnetic field 01024 // 01025 // Revision 1.12 2006/08/15 23:40:59 genevb 01026 // Averaging was done improperly in DontReset mode 01027 // 01028 // Revision 1.11 2006/07/17 20:13:08 genevb 01029 // Disallow SVT points on tracks 01030 // 01031 // Revision 1.10 2006/07/02 23:22:36 genevb 01032 // Allow for SVT/SSD hits on tracks (necessary for ITTF) 01033 // 01034 // Revision 1.9 2006/06/01 17:27:11 genevb 01035 // Bug fix: gapd and gapf backwards; Improvements: gap fit intercepts, hist and fit ranges 01036 // 01037 // Revision 1.8 2006/01/05 19:12:53 genevb 01038 // Added calib mode 01039 // 01040 // Revision 1.7 2005/12/07 19:45:46 perev 01041 // Histos diconnected from directory. EndCrashFix 01042 // 01043 // Revision 1.6 2005/04/21 19:38:20 genevb 01044 // Additional code for studying SpaceCharge 01045 // 01046 // Revision 1.5 2005/02/16 17:18:06 genevb 01047 // Fill StEvent info on SpaceCharge 01048 // 01049 // Revision 1.4 2004/08/13 20:49:12 genevb 01050 // Improve upon keeping method locked on for each event, and timestamp change 01051 // 01052 // Revision 1.3 2004/08/02 01:19:27 genevb 01053 // minor fixes for getting directories correct 01054 // 01055 // Revision 1.2 2004/07/01 01:46:04 genevb 01056 // Slightly larger margin for full vs half field differences 01057 // 01058 // Revision 1.1 2004/06/30 23:16:00 genevb 01059 // Introduction of StSpaceChargeEbyEMaker 01060 // 01061 //

Generated on Sun Mar 15 04:55:03 2009 for StRoot by doxygen 1.3.7