DRAGON Analyzer
Classes | Public Member Functions | Public Attributes | Private Member Functions | Private Attributes | List of all members
dragon::BeamNorm Class Reference

Class to handle calculation of beam normalization. More...

#include <RootAnalysis.hxx>

Inheritance diagram for dragon::BeamNorm:
Inheritance graph
[legend]
Collaboration diagram for dragon::BeamNorm:
Collaboration graph
[legend]

Classes

struct  RunData
 Summarizes relevant normalization data for a run. More...
 

Public Member Functions

 BeamNorm ()
 Default constructor.
 
 BeamNorm (const char *name, const char *rossumFile)
 Construct from rossum file.
 
void ChangeRossumFile (const char *name)
 Switch to a new rossum file.
 
RossumDataGetRossumFile () const
 Get a pointer to the rossum file.
 
void BatchCalculate (TChain *chain, Int_t chargeBeam, Double_t pkLow0, Double_t pkHigh0, Double_t pkLow1, Double_t pkHigh1, const char *recoilGate=0, Double_t time=120, Double_t skipBegin=10, Double_t skipEnd=5)
 Batch calculate over a chain of files.
 
void BatchCalculate (TChain *chain, Int_t chargeBeam, Double_t pkLow0, Double_t pkHigh0, Double_t pkLow1, Double_t pkHigh1, const TCut &recoilGate, Double_t time=120, Double_t skipBegin=10, Double_t skipEnd=5)
 BatchCalculate overloaded with non-null recoil gate.
 
void CalculateRecoils (TFile *datafile, const char *tree, const char *gate)
 Calculate the number of recoils per run.
 
Int_t ReadSbCounts (TFile *datafile, Double_t pkLow0, Double_t pkHigh0, Double_t pkLow1, Double_t pkHigh1, Double_t time=120.)
 
void ReadFC4 (Int_t runnum, Double_t skipBegin=10, Double_t skipEnd=5)
 Read rossum FC4 current.
 
void CalculateNorm (Int_t run, Int_t chargeState)
 Calculate R and total beam particles.
 
RunDataGetRunData (Int_t runnum)
 Return stored values of run data.
 
std::vector< Int_t > & GetRuns () const
 Return a vector of run numbers used in the calculation.
 
TGraphAsymmErrors * Plot (const char *param, Marker_t marker=20, Color_t markerColor=kBlack)
 
TGraphErrors * PlotVal (const TString &valstr, int which=0, Marker_t marker=20, Color_t markerColor=kBlack, Option_t *option="")
 
TGraphErrors * PlotNbeam (double sbnorm, int which=0, Marker_t marker=21, Color_t markerColor=kBlack)
 Plot number of beam particles with manual sbnorm specification.
 
Long64_t Draw (const char *varexp, const char *selection, Option_t *option="", Long64_t nentries=1000000000, Long64_t firstentry=0)
 Draw run data information.
 
void Draw (Option_t *option)
 
UDouble_t GetEfficiency (const char *name) const
 
void SetEfficiency (const char *name, UDouble_t value)
 
void SetEfficiency (const char *name, Double_t value)
 
void CorrectTransmission (Int_t reference)
 
UDouble_t CalculateEfficiency (Bool_t print=kTRUE)
 
UDouble_t CalculateYield (Int_t whichSb, Int_t type=kHiSingles, Bool_t print=kTRUE)
 

Public Attributes

TTree fRunDataTree
 

Private Member Functions

RunDataGetOrCreateRunData (Int_t runnum)
 Private GetRunData(), creates new if it's not made.
 
Bool_t HaveRossumFile ()
 
UInt_t GetParams (const char *param, std::vector< Double_t > *runnum, std::vector< UDouble_t > *parval)
 
 BeamNorm (const BeamNorm &)
 
BeamNormoperator= (const BeamNorm &)
 
 ClassDef (BeamNorm, 2)
 

Private Attributes

RunDatafRunDataBranchAddr
 
std::map< Int_t, RunDatafRunData
 
dragon::utils::AutoPtr< RossumDatafRossum
 
std::map< std::string, UDouble_tfEfficiencies
 

Detailed Description

Class to handle calculation of beam normalization.

Definition at line 295 of file RootAnalysis.hxx.

Member Function Documentation

◆ CorrectTransmission()

void dragon::BeamNorm::CorrectTransmission ( Int_t  reference)

Correct for FC4->FC1 transmission changes relative to a single "good" run

Corrects the yield and nbeam values for each run such that the transmission matches the reference run.

Parameters
referenceRun number of the reference run.
Todo:
Change nbeam to nbeam_fc4 and nbeam_fc1 or something like that becuse now it's confusing to change both yield and nbeam and not explicit enough what's going on.

Definition at line 1394 of file RootAnalysis.cxx.

References dragon::BeamNorm::RunData::fc1, dragon::BeamNorm::RunData::fc4, dragon::BeamNorm::RunData::nbeam, dragon::BeamNorm::RunData::trans_corr, and dragon::BeamNorm::RunData::yield.

1395 {
1396  RunData* refData = GetRunData(reference);
1397  if(!refData) {
1398  std::cerr << "Cound not find run data for reference run " << reference << "\n";
1399  return;
1400  }
1401  UDouble_t transRef = refData->fc1 / UDouble_t::Mean(3, refData->fc4);
1402 
1403  for(std::map<Int_t, RunData>::iterator it = fRunData.begin(); it != fRunData.end(); ++it) {
1404  RunData& thisData = it->second;
1405  UDouble_t transThis = thisData.fc1 / UDouble_t::Mean(3, thisData.fc4);
1406  if(it->first != reference)
1407  thisData.trans_corr = (transThis / transRef);
1408  else
1409  thisData.trans_corr = UDouble_t(1, 0);
1410 
1411  for(int i=0; i< NSB; ++i) {
1412  thisData.yield[i] /= thisData.trans_corr;
1413  thisData.nbeam[i] /= thisData.trans_corr;
1414  }
1415  }
1416 }
RunData * GetRunData(Int_t runnum)
Return stored values of run data.

◆ Plot()

TGraphAsymmErrors * dragon::BeamNorm::Plot ( const char *  param,
Marker_t  marker = 20,
Color_t  markerColor = kBlack 
)

Plot some parameter as a function of run number

Parameters
paramString specifying the parameter to plot, should be a member of dragon::BeamNorm::RunData
markerMarker symbol
markerColorMarker color
Returns
TGraph pointer containing param vs. run number, responsibility is on the user to delete this. In case of error, returns 0.

Also draws the returned TGraph in its own window.

Definition at line 1135 of file RootAnalysis.cxx.

1136 {
1137  TGraphAsymmErrors* gr = 0;
1138  std::vector<Double_t> runnum;
1139  std::vector<UDouble_t> parval;
1140  UInt_t npar = GetParams(param, &runnum, &parval);
1141  if(npar) {
1142  gr = PlotUncertainties(runnum.size(), &runnum[0], &parval[0]);
1143  gr->SetMarkerStyle(marker);
1144  gr->SetMarkerColor(markerColor);
1145  gr->Draw("AP");
1146  }
1147  return gr;
1148 }

◆ PlotVal()

TGraphErrors * dragon::BeamNorm::PlotVal ( const TString &  valstr,
int  which = 0,
Marker_t  marker = 20,
Color_t  markerColor = kBlack,
Option_t *  option = "" 
)

Plot some parameter as a function of run number (alt. implementation)

Parameters
valstrString specifying the parameter to plot, should be a member of dragon::BeamNorm::RunData
whichSpecifies which array index to plot, ignored if valstr is not an array
markerMarker symbol
markerColorMarker color
Returns
TGraphErrors pointer containing param vs. run number, responsibility is on the user to delete this. In case of error, returns 0.

Also draws the returned TGraph in its own window.

Definition at line 1161 of file RootAnalysis.cxx.

References dragon::BeamNorm::RunData::fc1, dragon::BeamNorm::RunData::fc4, dragon::BeamNorm::RunData::live_time, dragon::BeamNorm::RunData::live_time_coinc, dragon::BeamNorm::RunData::live_time_head, dragon::BeamNorm::RunData::live_time_tail, dragon::BeamNorm::RunData::nbeam, dragon::BeamNorm::RunData::nrecoil, dragon::BeamNorm::RunData::pressure, dragon::BeamNorm::RunData::pressure_full, dragon::BeamNorm::RunData::runnum, dragon::BeamNorm::RunData::sb_counts, dragon::BeamNorm::RunData::sb_counts_full, dragon::BeamNorm::RunData::sbnorm, dragon::BeamNorm::RunData::trans_corr, and dragon::BeamNorm::RunData::yield.

1163 {
1164  std::vector<double> rn, val, err;
1165  for(size_t i=0; i< GetRuns().size(); ++i) {
1166  const dragon::BeamNorm::RunData* rd = GetRunData(GetRuns()[i]);
1167  rn.push_back(rd->runnum);
1168  if(0) {
1169  }
1170  else if(valstr == "sb_counts") {
1171  val.push_back(rd->sb_counts[which].GetNominal());
1172  err.push_back(rd->sb_counts[which].GetErrLow());
1173  }
1174  else if(valstr == "sb_counts_full") {
1175  val.push_back(rd->sb_counts_full[which].GetNominal());
1176  err.push_back(rd->sb_counts_full[which].GetErrLow());
1177  }
1178  else if(valstr == "live_time") {
1179  val.push_back(rd->live_time.GetNominal());
1180  err.push_back(rd->live_time.GetErrLow());
1181  }
1182  else if(valstr == "live_time_tail") {
1183  val.push_back(rd->live_time_tail.GetNominal());
1184  err.push_back(rd->live_time_tail.GetErrLow());
1185  }
1186  else if(valstr == "live_time_head") {
1187  val.push_back(rd->live_time_head.GetNominal());
1188  err.push_back(rd->live_time_head.GetErrLow());
1189  }
1190  else if(valstr == "live_time_coinc") {
1191  val.push_back(rd->live_time_coinc.GetNominal());
1192  err.push_back(rd->live_time_coinc.GetErrLow());
1193  }
1194  else if(valstr == "pressure") {
1195  val.push_back(rd->pressure.GetNominal());
1196  err.push_back(rd->pressure.GetErrLow());
1197  }
1198  else if(valstr == "pressure_full") {
1199  val.push_back(rd->pressure_full.GetNominal());
1200  err.push_back(rd->pressure_full.GetErrLow());
1201  }
1202  else if(valstr == "fc4") {
1203  val.push_back(rd->fc4[which].GetNominal());
1204  err.push_back(rd->fc4[which].GetErrLow());
1205  }
1206  else if(valstr == "fc1") {
1207  val.push_back(rd->fc1.GetNominal());
1208  err.push_back(rd->fc1.GetErrLow());
1209  }
1210  else if(valstr == "trans_corr") {
1211  val.push_back(rd->trans_corr.GetNominal());
1212  err.push_back(rd->trans_corr.GetErrLow());
1213  }
1214  else if(valstr == "sbnorm") {
1215  val.push_back(rd->sbnorm[which].GetNominal());
1216  err.push_back(rd->sbnorm[which].GetErrLow());
1217  }
1218  else if(valstr == "nbeam") {
1219  val.push_back(rd->nbeam[which].GetNominal());
1220  err.push_back(rd->nbeam[which].GetErrLow());
1221  }
1222  else if(valstr == "nrecoil") {
1223  val.push_back(rd->nrecoil.GetNominal());
1224  err.push_back(rd->nrecoil.GetErrLow());
1225  }
1226  else if(valstr == "yield") {
1227  val.push_back(rd->yield[which].GetNominal());
1228  err.push_back(rd->yield[which].GetErrLow());
1229  }
1230  else {
1231  std::cerr << "Invalid parameter << \"" << valstr.Data() << "\"\n";
1232  break;
1233  }
1234  }
1235  TGraphErrors* gr = 0;
1236  if(val.size()) {
1237  gr = new TGraphErrors(rn.size(), &rn[0], &val[0], 0, &err[0]);
1238  gr->SetMarkerStyle(marker);
1239  gr->SetMarkerColor(markerColor);
1240  gr->SetLineColor(markerColor);
1241  gr->Draw(option);
1242  }
1243  return gr;
1244 }
UDouble_t pressure
Average pressure in sb_time.
Summarizes relevant normalization data for a run.
std::vector< Int_t > & GetRuns() const
Return a vector of run numbers used in the calculation.
UDouble_t fc4[3]
FC4 current, per iteration.
UDouble_t live_time_head
Head live time across the whole run.
UDouble_t fc1
FC1 current.
UDouble_t live_time
Live time in time used for SB normalization.
RunData * GetRunData(Int_t runnum)
Return stored values of run data.
UDouble_t trans_corr
Transmission correction.
UDouble_t pressure_full
Average pressure across the whole run.
UDouble_t live_time_coinc
Coinc live time across the whole run.
UDouble_t sb_counts_full[dragon::SurfaceBarrier::MAX_CHANNELS]
Number of sb counts in the whole run.
UDouble_t yield[dragon::SurfaceBarrier::MAX_CHANNELS]
Yield, per SB norm.
UDouble_t nbeam[dragon::SurfaceBarrier::MAX_CHANNELS]
Total integrated beam particles for the run.
UDouble_t sb_counts[dragon::SurfaceBarrier::MAX_CHANNELS]
Number of surface barrier counts in time, per detector.
Int_t runnum
The run number.
UDouble_t live_time_tail
Tail live time across the whole run.
UDouble_t sbnorm[dragon::SurfaceBarrier::MAX_CHANNELS]
Normalization factor R, per sb detector.
UDouble_t nrecoil
Number of recoils.

◆ ReadSbCounts()

Int_t dragon::BeamNorm::ReadSbCounts ( TFile *  datafile,
Double_t  pkLow0,
Double_t  pkHigh0,
Double_t  pkLow1,
Double_t  pkHigh1,
Double_t  time = 120. 
)

Integrate the surface barrier counts at the beginning and end of a run

Calculates the "R-value" to normalize SB readings to Faraday cup data. Stores the result in fRunData, they can be accessed by using GetRunData()

Parameters
datafilePointer to the run's ROOT file
pkLow0Low end of the SB0 good peak
pkHigh0High end of the SB0 good peak
pkLow1Low end of the SB1 good peak
pkHigh1High end of the SB1 good peak
timeNumber of seconds at the beginning of the run to use for calculating the normalization
Returns
The run number of the specified file.

Definition at line 859 of file RootAnalysis.cxx.

References dragon::LiveTimeCalculator::Calculate(), dragon::utils::calculate_mean(), dragon::utils::calculate_stddev(), dragon::LiveTimeCalculator::CalculateSub(), dragon::Epics::ch, dragon::LiveTimeCalculator::GetLivetime(), dragon::Tail::header, dragon::Epics::header, dragon::BeamNorm::RunData::live_time, dragon::BeamNorm::RunData::live_time_coinc, dragon::BeamNorm::RunData::live_time_head, dragon::BeamNorm::RunData::live_time_tail, dragon::BeamNorm::RunData::pressure, dragon::BeamNorm::RunData::pressure_full, midas::Database::ReadValue(), dragon::BeamNorm::RunData::sb_counts, dragon::BeamNorm::RunData::sb_counts_full, dragon::LiveTimeCalculator::SetFile(), dragon::BeamNorm::RunData::time, and dragon::Epics::val.

861 {
862  if(!HaveRossumFile()) {
863  std::cout << "\n";
864  dutils::Error("BeamNorm::ReadSbCounts", __FILE__, __LINE__)
865  << "no rossum file loaded.";
866  return 0;
867  }
868  if(!datafile || datafile->IsZombie()) {
869  std::cout << "\n";
870  dutils::Error("BeamNorm::ReadSbCounts", __FILE__, __LINE__)
871  << "Invalid datafile: " << datafile;
872  return 0;
873  }
874 
875  Bool_t haveRunnum = kFALSE;
876  Int_t runnum = 0;
877  midas::Database* db = static_cast<midas::Database*>(datafile->Get("odbstop"));
878 
879  if (db) haveRunnum = db->ReadValue("/Runinfo/Run number", runnum);
880  else {
881  std::cout << "\n";
882  dutils::Warning("BeamNorm::ReadSbCounts", __FILE__, __LINE__)
883  << "MIDAS database at run stop time missing from file " << datafile->GetName() << "\n";
884  midas::Database* dbstart = static_cast<midas::Database*>(datafile->Get("odbstart"));
885  if (dbstart) haveRunnum = dbstart->ReadValue("/Runinfo/Run number", runnum);
886  else {
887  std::cout << "\n";
888  dutils::Error("BeamNorm::ReadSbCounts", __FILE__, __LINE__)
889  << "MIDAS database at run start time missing from file " << datafile->GetName() << "\n";
890  return 0;
891  }
892  }
893  if(!haveRunnum) {
894  std::cout << "\n";
895  dutils::Error("BeamNorm::ReadSbCounts", __FILE__, __LINE__)
896  << "could not read run number from file " << datafile->GetName();
897  return 0;
898  }
899 
900  TTree* t3 = static_cast<TTree*>(datafile->Get("t3"));
901  if(t3 == 0 || t3->GetListOfBranches()->At(0) == 0) {
902  std::cout << "\n";
903  dutils::Error("BeamNorm::ReadSbCounts", __FILE__, __LINE__)
904  << "no heavy-ion data tree in file" << datafile->GetName();
905  return 0;
906  }
907 
908  TTree* t20 = static_cast<TTree*>(datafile->Get("t20"));
909  if(t20 == 0 || t20->GetListOfBranches()->At(0) == 0) {
910  dutils::Error("BeamNorm::ReadSbCounts", __FILE__, __LINE__)
911  << "no EPICS tree in file" << datafile->GetName();
912  return 0;
913  }
914 
915  dragon::Tail tail;
916  dragon::Tail *pTail = &tail;
917  t3->SetBranchAddress(t3->GetListOfBranches()->At(0)->GetName(), &pTail);
918 
919  dragon::Epics epics;
920  dragon::Epics* pEpics = &epics;
921  t20->SetBranchAddress(t20->GetListOfBranches()->At(0)->GetName(), &pEpics);
922 
923  AutoResetBranchAddresses Rst3_(t3);
924  AutoResetBranchAddresses Rst20_(t20);
925 
926  Long64_t ncounts[NSB];
927  Long64_t ncounts_full[NSB];
928  for(int i=0; i< NSB; ++i) {
929  ncounts[i] = 0;
930  ncounts_full[i] = 0;
931  }
932 
933  t3->GetEntry(0);
934  Double_t tstart = pTail->header.fTimeStamp;
935  Double_t low[NSB] = { pkLow0, pkLow1 };
936  Double_t high[NSB] = { pkHigh0, pkHigh1 };
937 
938  for(int i=0; i< NSB; ++i) {
939  std::stringstream cut;
940  cut.precision(20);
941  cut << "sb.ecal[" << i << "] > " << low[i] << " && sb.ecal[" << i << "] < " << high[i];
942  ncounts_full[i] = t3->GetPlayer()->GetEntries(cut.str().c_str());
943 
944  cut << " && header.fTimeStamp - " << tstart << " < " << time;
945  ncounts[i] = t3->GetPlayer()->GetEntries(cut.str().c_str());
946  }
947 
948  UDouble_t live, live_full[3]; // [3]: head,tail,coinc
949  {
951  ltc.SetFile(datafile);
952  ltc.CalculateSub(0, time);
953  live = ltc.GetLivetime("tail");
954  ltc.Calculate();
955  live_full[0] = ltc.GetLivetime("head");
956  live_full[1] = ltc.GetLivetime("tail");
957  live_full[2] = ltc.GetLivetime("coinc");
958  }
959 
960  t20->GetEntry(0);
961  Double_t tstart20 = pTail->header.fTimeStamp;
962  Int_t t1 = 0;
963  std::vector<double> pressure;
964 
965  for(Long64_t entry = 0; entry != t20->GetEntries(); ++entry) {
966  t20->GetEntry(entry);
967  if(pEpics->ch == 0) {
968  pressure.push_back(pEpics->val);
969  if(pEpics->header.fTimeStamp - tstart20 < time)
970  ++t1;
971  }
972  }
973 
974  RunData* rundata = GetOrCreateRunData(runnum);
975  rundata->time = time;
976  for(int i=0; i< NSB; ++i) {
977  rundata->sb_counts[i] = UDouble_t(ncounts[i]);
978  rundata->sb_counts_full[i] = UDouble_t(ncounts_full[i]);
979  }
980  //
981  // Pressure over SB norm time
982  {
983  const Double_t pressureMean = utils::calculate_mean(pressure.begin(), pressure.begin() + t1);
984  const Double_t pressureSigma = utils::calculate_stddev(pressure.begin(),
985  pressure.begin() + t1, pressureMean);
986  rundata->pressure = UDouble_t (pressureMean, pressureSigma);
987  }
988  //
989  // Pressure over full run
990  {
991  const Double_t pressureMean = utils::calculate_mean(pressure.begin(), pressure.end());
992  const Double_t pressureSigma = utils::calculate_stddev(pressure.begin(),
993  pressure.end(), pressureMean);
994  rundata->pressure_full = UDouble_t (pressureMean, pressureSigma);
995  }
996  rundata->live_time = live;
997  rundata->live_time_head = live_full[0];
998  rundata->live_time_tail = live_full[1];
999  rundata->live_time_coinc = live_full[2];
1000 
1001  return runnum;
1002 }
std::iterator_traits< InputIterator >::value_type calculate_mean(InputIterator first, InputIterator last)
Calculate the mean of a range of values.
Definition: Functions.hxx:679
void Calculate()
Perform live time calculation across an entire run.
int32_t ch
Epics channel number for this event.
Definition: Dragon.hxx:875
Generic database reading class.
Definition: Database.hxx:42
Specialized Strm class to print warning messages.
float val
EPICS value at ch for this event.
Definition: Dragon.hxx:877
TMidas_EVENT_HEADER header
Midas event header.
Definition: Dragon.hxx:873
Live time calculator.
std::iterator_traits< InputIterator >::value_type calculate_stddev(InputIterator first, InputIterator last, typename std::iterator_traits< InputIterator >::value_type mean)
Calculate the standard deviation of a range of values.
Definition: Functions.hxx:718
bool ReadValue(const char *path, T &value) const
Read a single value.
Definition: Database.hxx:132
TMidas_EVENT_HEADER header
Midas event header.
Definition: Dragon.hxx:637
Double_t GetLivetime(const char *which) const
Returns the live time fraction.
void CalculateSub(Double_t tbegin, Double_t tend)
Perform live time calculation across a subset of the run.
Specialized Strm class to print error messages.
RunData * GetOrCreateRunData(Int_t runnum)
Private GetRunData(), creates new if it&#39;s not made.
void SetFile(TFile *file)
Change the run file.
Here is the call graph for this function:

The documentation for this class was generated from the following files: