14 #include "StVertexSeedMaker.h"
15 #include "StDbLib/StDbManager.hh"
16 #include "StDbLib/StDbConfigNode.hh"
17 #include "StDbLib/StDataBaseI.hh"
18 #include "StDetectorDbMaker/StDetectorDbTriggerID.h"
19 #include "StMessMgr.h"
20 #include "StVertexId.h"
21 #include "tables/St_vertexSeed_Table.h"
22 #include "tables/St_vertexSeedTriggers_Table.h"
23 #include "tables/St_beamInfo_Table.h"
26 #include "TVirtualFitter.h"
29 #include "TTimeStamp.h"
30 #include "TEventList.h"
37 static TArrayF xVert, yVert, zVert, multA, exVert, eyVert;
40 double funcX(
float z,Double_t *par) {
41 double x = par[0] + par[1]*z;
44 double funcY(
float z,Double_t *par) {
45 double y = par[2] + par[3]*z;
48 void fnch(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag) {
51 for (
int i=0;i<nverts; i++) {
54 double delta_sq, error_sq;
63 error_sq = 0.0016 + (2.45 / multA[i]);
64 delta_sq = TMath::Power(xVert[i]-funcX(zVert[i],par),2) +
65 TMath::Power(yVert[i]-funcY(zVert[i],par),2);
66 chisq += (delta_sq/error_sq);
73 double errx2 = exVert[i]*exVert[i] + beamWidth*beamWidth;
74 double erry2 = eyVert[i]*eyVert[i] + beamWidth*beamWidth;
75 chisq += TMath::Power(xVert[i]-funcX(zVert[i],par),2)/errx2 +
76 TMath::Power(yVert[i]-funcY(zVert[i],par),2)/erry2;
82 void setArraySize(
int n) {
91 void addVert(
float x,
float y,
float z,
float m,
float ex,
float ey) {
92 if (nverts >= nsize) setArraySize(nsize*2);
107 const
char* defaultDir):
StMaker(name){
109 xdist =
new TH1F(
"xdist",
"xdist",1000,HIST_MIN,HIST_MAX);
110 ydist =
new TH1F(
"ydist",
"ydist",1000,HIST_MIN,HIST_MAX);
111 xerr =
new TH1F(
"xerr",
"x measured - x guess",1000,HIST_MIN,HIST_MAX);
112 yerr =
new TH1F(
"yerr",
"y measured - y guess",1000,HIST_MIN,HIST_MAX);
122 useAllTriggers = kFALSE;
136 void StVertexSeedMaker::Reset() {
144 if (mTempOut)
delete mTempOut;
145 else delete resNtuple;
146 mTempOut =
new TFile(Form(
"%s/vertexseedhist.%d.root",
147 gSystem->TempDirectory(),
148 gSystem->GetPid()),
"RECREATE");
149 resNtuple =
new TNtuple(
"resNtuple",
"resNtuple",
"event:x:y:z:mult:trig:run:fill:zdc:rank:itpc:otpc:detmap:ex:ey:index:bmatch:ematch:tmatch:cmatch:hmatch:pmatch:pct:vpdz:tDay:tFill");
150 LOG_INFO <<
"Opening new temp file at " << mTempOut->GetName() << endm;
165 StVertexSeedMaker::~StVertexSeedMaker(){
168 Int_t StVertexSeedMaker::Init(){
173 return StMaker::Init();
188 vpd_zvertex = -999.0;
206 if (date==0) GetADateTime();
210 LOG_INFO <<
"Reading db values at the start..." << endm;
211 int status = FillAssumed();
212 if (status !=
kStOk)
return status;
213 status = GetVertexSeedTriggers();
214 if (status !=
kStOk)
return status;
217 if (CheckTriggers()) {
218 LOG_INFO <<
"event does not satisfy triggers" << endm;
222 int eventResult = GetEventData();
223 if (eventResult !=
kStOk)
return eventResult;
226 LOG_INFO <<
"No primary vertex" << endm;
231 xguess = a[0] + (a[1] * zvertex);
232 yguess = a[2] + (a[3] * zvertex);
233 LOG_INFO <<
"x guess = " << xguess << endm;
234 LOG_INFO <<
"y guess = " << yguess << endm;
237 float r2vertex = xvertex*xvertex + yvertex*yvertex;
238 if ((zvertex > zVertexMin) && (zvertex < zVertexMax) &&
239 (mult >= 5) && (r2vertex < r2VertexMax)){
240 xdist->Fill(xvertex);
241 xerr ->Fill(xvertex-xguess);
242 ydist->Fill(yvertex);
243 yerr ->Fill(yvertex-yguess);
246 XX[0] = (float) GetEventNumber();
252 XX[6] = (float) (run % 1000000);
253 XX[7] = (float) fill;
256 XX[10] = (float) itpc;
257 XX[11] = (float) otpc;
258 XX[12] = (float) detmap;
261 XX[15] = (float) pvn;
262 XX[16] = (float) bmatch;
263 XX[17] = (float) ematch;
264 XX[18] = (float) tmatch;
265 XX[19] = (float) cmatch;
266 XX[20] = (float) hmatch;
267 XX[21] = (float) pmatch;
268 XX[22] = (float) pct;
269 XX[23] = vpd_zvertex;
270 XX[24] = (float) (timeEvent % 86400);
271 XX[25] = (float) (timeFill >=0 ? timeEvent - timeFill : timeFill);
273 addVert(xvertex,yvertex,zvertex,mult,exvertex,eyvertex);
285 bool StVertexSeedMaker::ValidTrigger(
unsigned int tid) {
287 if (!dbTriggersTable)
return kTRUE;
288 vertexSeedTriggers_st* trigsTable = dbTriggersTable->GetTable();
289 int nTrigs = (int) (dbTriggersTable->GetNRows());
290 for (
int i = 0; i < nTrigs; i++, trigsTable++) {
291 unsigned int dbTid = trigsTable->trigid;
292 if (useAllTriggers || dbTid == 9999999 || (dbTid > 0 && tid == dbTid)) {
300 void StVertexSeedMaker::FindResult(
bool checkDb) {
301 bool writeIt = kFALSE;
302 if (nverts >= minEntries){
304 if (ep[0] > maxX0Err){
305 LOG_ERROR <<
"x unstable. x0 error = " << ep[0] <<
" cm." << endm;
307 if (ep[2] > maxY0Err){
308 LOG_ERROR <<
"y unstable. y0 error = " << ep[2] <<
" cm." << endm;
310 if ((ep[0] <= maxX0Err) && (ep[2] <= maxY0Err)) {
314 LOG_INFO <<
"Reading db values at the end..." << endm;
315 int status = FillAssumed();
316 if (status ==
kStOk) {
317 if (ChangedValues() || BetterErrors()) writeIt = kTRUE;
318 else { LOG_INFO <<
"Values have not changed/improved." << endm; }
320 LOG_WARN <<
"Could not get db values." << endm;
328 LOG_ERROR <<
"Insufficient stats for " <<
329 "mean vertex determination.\n Only " << nverts <<
" entries." << endm;
332 if (writeIt) WriteTableToFile();
333 else { LOG_WARN <<
"Not writing table!!!!!" << endm; }
335 if (mHistOut) WriteHistFile(writeIt);
338 void StVertexSeedMaker::PrintInfo() {
339 LOG_INFO <<
"\n**************************************************************"
340 <<
"\n* $Id: StVertexSeedMaker.cxx,v 1.64 2017/08/08 03:58:20 genevb Exp $"
341 <<
"\n**************************************************************" << endm;
343 if (Debug()) StMaker::PrintInfo();
346 void StVertexSeedMaker::WriteTableToFile(){
347 TString fileName = NameFile(
"table",
"vertexSeed",
"C");
348 ofstream *out =
new ofstream(fileName.Data());
349 St_vertexSeed* vertexSeedTable = VertexSeedTable();
350 vertexSeedTable->SavePrimitive(*out,
"");
351 if (parsNtuple) AddResults(parsNtuple);
353 delete vertexSeedTable;
357 void StVertexSeedMaker::AddResults(TNtupleD* ntup){
358 double datetime = ((double) date) + 1e-6*((double) time);
359 TTimeStamp dt1(date,time,0,
true,0);
360 dt1.SetSec(dt1.GetSec() - 4*60*60);
361 int tm = dt1.GetTime();
362 int se = tm%100;
int hm = (tm-se)/100;
363 int mn = hm%100;
int hr = (hm-mn)/100;
364 double days = ((double) dt1.GetDayOfYear()) +
365 ((
double) ((hr*60+mn)*60+se))/(24.*60.*60.);
366 ntup->Fill(days,p[0],ep[0],p[2],ep[2],p[1],ep[1],p[3],ep[3],
367 (
double) nverts, datetime, (
double) fill,
368 sumzdc/((
double) nverts),chi,beamWidth);
371 St_vertexSeed* StVertexSeedMaker::VertexSeedTable(){
373 St_vertexSeed* table =
new St_vertexSeed(
"vertexSeed",1);
374 vertexSeed_st* row = table->GetTable();
380 row->err_dxdz = ep[1];
382 row->err_dydz = ep[3];
383 row->chisq_dof = chi;
385 row->stats = (float) nverts;
390 void StVertexSeedMaker::WriteHistFile(
bool writeFit){
391 if (resNtuple->GetEntries() == 0) {
392 LOG_INFO <<
"Not writing histograms - no entries!!!" << endm;
396 TString fileName = NameFile(
"histograms",
"vertexseedhist",
"ROOT");
400 if (gSystem->CopyFile(mTempOut->GetName(),fileName.Data()) ||
401 gSystem->Unlink(mTempOut->GetName())) {
402 LOG_ERROR <<
"Could not copy and/or delete temp vertexseedhist file!" << endm;
407 }
else delete resNtuple;
410 TFile out(fileName.Data(),
"UPDATE");
411 GetHistList()->Write();
414 AddResults(newBLpars());
420 TString StVertexSeedMaker::NameFile(
const char* type,
const char* prefix,
const char* suffix) {
424 TDatime fdatime(date,time);
425 fdatime.Set(fdatime.Convert()+foffset);
426 fdate = fdatime.GetDate();
427 ftime = fdatime.GetTime();
429 TString fileNameBase = Form(
"%s.%08d.%06d.%s",prefix,fdate,ftime,suffix);
431 if (defDir.Length()>0 && !defDir.EndsWith(
"/")) defDir.Append(
"/");
432 TString fileName = defDir;
433 fileName += fileNameBase;
434 LOG_INFO <<
"Writing new " << type <<
" to:\n "
436 TString dirname = gSystem->DirName(fileName.Data());
437 if (gSystem->OpenDirectory(dirname.Data())==0) {
438 if (gSystem->mkdir(dirname.Data())) {
439 LOG_WARN <<
"Directory creation failed for:\n " << dirname
440 <<
"\n Putting " << type <<
" file in current directory" << endm;
441 fileName = fileNameBase;
444 TString searchFile = fileName;
445 if (gSystem->FindFile(
".",searchFile)) {
448 LOG_WARN <<
"Existing file: trying 1 second later (offset="
449 << foffset <<
")..." << endm;
450 fileName = NameFile(type,prefix,suffix);
453 LOG_WARN <<
"Existing file: overwriting!" << endm;
459 int StVertexSeedMaker::FillAssumed(){
460 TDataSet* dbDataSet = GetDataBase(
"Calibrations/rhic/vertexSeed");
461 memset( a,0,4*
sizeof(
double));
462 memset(ea,0,4*
sizeof(
double));
464 LOG_WARN <<
"Could not find Calibrations/rhic/vertexSeed in database" << endm;
466 St_vertexSeed* dbTableC =
467 static_cast<St_vertexSeed*
>(dbDataSet->FindObject(
"vertexSeed"));
469 LOG_WARN <<
"Could not find vertexSeed in database" << endm;
471 vertexSeed_st*
dbTable = dbTableC->GetTable();
473 a[1] = dbTable->dxdz;
475 a[3] = dbTable->dydz;
476 ea[0] = dbTable->err_x0;
477 ea[1] = dbTable->err_dxdz;
478 ea[2] = dbTable->err_y0;
479 ea[3] = dbTable->err_dydz;
482 LOG_INFO <<
"Assumed values:"
483 <<
"\n x0 assumed = " << a[0] <<
" +/- " << ea[0]
484 <<
"\n dxdz assumed = " << a[1] <<
" +/- " << ea[1]
485 <<
"\n y0 assumed = " << a[2] <<
" +/- " << ea[2]
486 <<
"\n dydz assumed = " << a[3] <<
" +/- " << ea[3]
491 int StVertexSeedMaker::GetVertexSeedTriggers(){
492 TDataSet* dbDataSet = GetDataBase(
"Calibrations/rhic/vertexSeedTriggers");
494 LOG_ERROR <<
"Could not find Calibrations/rhic/vertexSeedTriggers in database" << endm;
498 static_cast<St_vertexSeedTriggers*
>(dbDataSet->FindObject(
"vertexSeedTriggers"));
499 if (!dbTriggersTable) {
500 LOG_ERROR <<
"Could not find vertexSeedTriggers in database" << endm;
506 bool StVertexSeedMaker::BetterErrors(){
507 bool better = kFALSE;
508 if ((ep[0] < ea[0]) || (ep[1] < ea[1]) ||
509 (ep[2] < ea[2]) || (ep[3] < ea[3])) better = kTRUE;
510 if (better) { LOG_INFO <<
"Values have improved" << endm; }
514 bool StVertexSeedMaker::ChangedValues(){
515 bool changed = kFALSE;
516 for (
int i = 0; i<4; i++) {
517 double diff = TMath::Abs(p[i] - a[i]);
518 if ((diff >= ep[i]) || (diff >= ea[i])) changed = kTRUE;
520 if (changed) { LOG_INFO <<
"Values have changed" << endm; }
524 void StVertexSeedMaker::GetADateTime() {
527 LOG_INFO <<
"event date = " << date << endm;
528 LOG_INFO <<
"event time = " << time << endm;
529 if (!useEventDateTime) GetFillDateTime();
532 void StVertexSeedMaker::GetFillDateTime() {
536 StDbTable* tab=node->addDbTable(
"beamInfo");
542 sprintf(queryStr,
"%08d %06d",date,time);
543 TString tdStr = queryStr;
544 tdStr.Insert(4,
'-').Insert(7,
'-').Insert(13,
':').Insert(16,
':');
545 const char* tdstr = tdStr.Data();
547 " where beginTime<='%s' and deactive=0 order by beginTime desc limit 1",
549 ts = db->QueryDb(tab,queryStr);
553 run = *(
static_cast<int*
>(tab->getDataValue(
"runNumber",0)));
554 LOG_INFO << tdstr <<
" is from run " << run << endm;
555 float thisFill = *(
static_cast<float*
>(tab->getDataValue(
"blueFillNumber",0)));
557 " where blueFillNumber=%f and deactive=0 order by beginTime asc limit 1",
559 db->QueryDb(tab,queryStr);
562 char* start = tab->getBeginDateTime();
563 fill = (int) thisFill;
564 time = atoi(&(start[8]));
567 timeFill = tab->getBeginTime();
569 LOG_INFO <<
"Using fill no. = " << fill << endm;
570 LOG_INFO <<
"Using fill date = " << date << endm;
571 LOG_INFO <<
"Using fill time = " << time << endm;
573 LOG_WARN <<
"Could not find beamInfo in database\n" <<
574 " Using event date/time." << endm;
579 void StVertexSeedMaker::FitData() {
580 LOG_INFO <<
"Now fitting the data..." <<
581 "\n *****************************************************" << endm;
582 TVirtualFitter *minuit = TVirtualFitter::Fitter(0,26);
584 minuit->SetFCN(fnch);
587 static Double_t pstart[4] = {0., 0., 0., 0.};
588 static Double_t pstep[4] = {0.0001, 0.0000001, 0.0001, 0.0000001};
589 static Double_t plow[4] = {-3., -0.05, -3., -0.05};
590 static Double_t phigh[4] = { 3., 0.05, 3., 0.05};
591 minuit->SetParameter(0,
"x0" , pstart[0], pstep[0], plow[0], phigh[0]);
592 minuit->SetParameter(1,
"dxdz", pstart[1], pstep[1], plow[1], phigh[1]);
593 minuit->SetParameter(2,
"y0" , pstart[2], pstep[2], plow[2], phigh[2]);
594 minuit->SetParameter(3,
"dydz", pstart[3], pstep[3], plow[3], phigh[3]);
603 int status = minuit->ExecuteCommand(
"MIGRAD", arglist ,1);
605 LOG_ERROR <<
"StVertexMaker: error on migrad call, err = "
610 double amin,edm,errdef;
612 minuit->GetStats(amin,edm,errdef,nvpar,nparx);
613 chi = amin/((double) (nverts-4));
614 LOG_INFO <<
"beamWidth = " << beamWidth <<
", chisq = " << amin <<
", chisq/dof = " << chi <<
615 "\n *****************************************************" << endm;
617 beamWidth += 0.005 * TMath::Min((
int) (chi*0.1+1),10);
618 }
while (chi>1.1 && beamWidth<=0.15);
621 for (
int i=0; i<4; i++)
622 minuit->GetParameter(i, pname, p[i], ep[i], plow[i], phigh[i]);
625 TNtupleD* StVertexSeedMaker::newBLpars() {
627 return new TNtupleD(
"BLpars",
"BeamLine parameters",
628 "days:x0:err_x0:y0:err_y0:dxdz:err_dxdz:dydz:err_dydz:stats:date:fill:zdc:chi:beamwidth");
631 void StVertexSeedMaker::Packer(
int firstbit,
int nbits,
int& var,
unsigned short val) {
635 int cap = ~((~0)<<nbits);
636 (detmap &= ~(cap<<firstbit)) |= (TMath::Min(var,cap)<<firstbit);
639 int StVertexSeedMaker::Aggregate(
char* dir,
const char* cuts,
const int offset) {
647 TFile parsOut(
"BLpars.root",
"RECREATE");
648 parsNtuple = newBLpars();
650 const char* defaultDir =
"./";
651 TString dirStr = dir;
652 if (!dir) dirStr = defaultDir;
653 if (dirStr.EndsWith(
"/")) dirStr.Append(
"vertexseedhist.*.root");
655 allFiles.AddFile(dirStr.Data());
658 const char* fileName;
659 for (
int fileb = 0; fileb < allFiles.GetNBundles(); fileb++) {
660 allFiles.GetNextBundle();
662 while ((fileName = allFiles.GetFileName(filen++))) {
663 fileList.Add(
new TNamed(fileName,fileName));
676 TString cutsStr = cuts;
677 if (cutsStr.Contains(
"ALL")) {
679 cutsStr.ReplaceAll(
"ALL&&",
"");
680 cutsStr.ReplaceAll(
"&&ALL",
"");
681 cutsStr.ReplaceAll(
"ALL",
"");
682 }
else if (cutsStr.Contains(
"DATE")) {
684 cutsStr.ReplaceAll(
"DATE&&",
"");
685 cutsStr.ReplaceAll(
"&&DATE",
"");
686 cutsStr.ReplaceAll(
"DATE",
"");
687 }
else if (cutsStr.Contains(
"FILE")) {
689 cutsStr.ReplaceAll(
"FILE&&",
"");
690 cutsStr.ReplaceAll(
"&&FILE",
"");
691 cutsStr.ReplaceAll(
"FILE",
"");
693 const char* cleanedCuts = cutsStr.Data();
696 static float prevX = -987.0;
698 TFile* currentFile=0;
700 int nfiles = fileList.GetSize();
701 for (
int filen = 0; filen < nfiles; filen++) {
705 fileName = fileList.At(filen)->GetName();
706 if (aggMode != 1 || date==0) {
707 TString dateTime = fileName;
708 dateTime.Remove(0,dateTime.Last(
'/') + 1);
709 dateTime.Remove(0,dateTime.First(
'.') + 1).
Remove(15);
710 TString dateStr = dateTime;
711 if (aggMode == 3) GetFillDateTime();
712 date = atoi(dateStr.Remove(8).Data());
713 time = atoi(dateTime.Remove(0,9).Remove(6).Data());
714 if (aggMode != 3) GetFillDateTime();
715 if (aggMode == 2) time = 0;
717 if ((currentFile) && (
718 (aggMode == 0 && fill != fillf) ||
719 (aggMode == 2 && date != datef) ||
721 LOG_INFO <<
"Aggregator has changed\n"
722 <<
" Processing data from previous aggregation before continuing" << endm;
726 int timeFillp = timeFill;
730 currentFile->Close();
737 timeFill = timeFillp;
740 LOG_INFO <<
"Now opening file:\n " << fileName << endm;
741 if (currentFile) currentFile->Close();
742 currentFile =
new TFile(fileName);
743 TNtuple* curNtuple =
static_cast<TNtuple*
>(currentFile->Get(
"resNtuple"));
745 LOG_ERROR <<
"No resNtuple found in " << fileName << endm;
748 curNtuple->Draw(
">>elistVtxSeed",cleanedCuts);
749 TEventList* elist =
static_cast<TEventList*
>(gDirectory->Get(
"elistVtxSeed"));
750 int nentries = (elist ? (int) elist->GetN() : 0);
751 int nvar = curNtuple->GetNvar();
752 int rvar = resNtuple->GetNvar();
753 for (
int entryn = 0; entryn < nentries; entryn++) {
754 curNtuple->GetEntry(elist->GetEntry(entryn));
755 vals = curNtuple->GetArgs();
756 if (vals[1] == prevX)
continue;
757 else prevX = vals[1];
758 unsigned int tid = (
unsigned int) vals[5];
759 bool updateForTimeFill = (nvar > 24 && timeFill >=0 &&
760 vals[24] >= 0 && vals[25] < 0);
761 if (ValidTrigger(tid)) {
762 if (nvar < rvar || updateForTimeFill) {
764 memset(vals2,0,32*
sizeof(
float));
765 memcpy(vals2,vals,nvar*
sizeof(
float));
768 detmap = (int) (vals[12]);
770 ematch = (detmap>>3)&7;
771 tmatch = (detmap>>6)&7;
772 cmatch = (detmap>>9)&3;
773 hmatch = (detmap>>11)&7;
774 vals2[16] = (float) bmatch;
775 vals2[17] = (float) ematch;
776 vals2[18] = (float) tmatch;
777 vals2[19] = (float) cmatch;
778 vals2[20] = (float) hmatch;
781 vals2[21] = (float) pmatch;
782 vals2[22] = (float) pct;
783 vals2[23] = vpd_zvertex;
786 vals2[24] = (float) (timeEvent % 86400);
787 vals2[25] = (float) (timeFill >= 0 ? timeEvent - timeFill : timeFill);
788 }
else if (updateForTimeFill) {
790 int timeTemp = ((int) vals[24]) - (timeFill % 86400);
791 while (timeTemp < 0) timeTemp += 86400;
792 vals2[25] = (float) timeTemp;
794 resNtuple->Fill(vals2);
796 resNtuple->Fill(vals);
798 addVert(vals[1],vals[2],vals[3],vals[4],vals[13],vals[14]);
800 addVert(vals[1],vals[2],vals[3],vals[4],0.,0.);
803 LOG_INFO <<
"Invalid trigger: " << tid << endm;
806 LOG_INFO <<
"Current statistics: " << nverts << endm;
809 currentFile->Close();
816 LOG_INFO <<
"Examined " << nfiles <<
" files" << endm;
virtual void Remove(TDataSet *set)
Remiove the "set" from this TDataSet.
virtual void Clear(Option_t *option)
User defined functions.
static StDbManager * Instance()
strdup(..) is not ANSI
BeamLine Constraint calibration base class.