// Do the extraction of the actual constants void ExtractTimeOffsetsAndCEff(int run = 2931, TString filename = "hd_root.root") { // Open our input and output file thisFile = TFile::Open(filename); TFile *outputFile = TFile::Open("BCALTimeOffsetAndCEff_Results.root", "RECREATE"); outputFile->mkdir("Fits"); outputFile->mkdir("ResultOverview"); // Check to make sure it is open if (thisFile == 0) { cout << "Unable to open file " << fileName.Data() << "...Exiting" << endl; return; } // We need to have the value of C_effective used for the position determination to get the time offsets double C_eff = 16.75; // cm/ns // Since we are updating existing constants we will need their current values. We can pipe them in from the CCDB... // We need a place to store them... double tdc_offsets[1152]; double adc_offsets[1536]; //Pipe the current constants into this macro //NOTE: This dumps the "LATEST" values. If you need something else, modify this script. char command[100]; sprintf(command, "ccdb dump /BCAL/TDC_offsets:%i:default", run); FILE* locInputFile = gSystem->OpenPipe(command, "r"); if(locInputFile == NULL) return 0; //get the first (comment) line char buff[1024]; if(fgets(buff, sizeof(buff), locInputFile) == NULL) return 0; //get the remaining lines double time; int counter = 0; while(fgets(buff, sizeof(buff), locInputFile) != NULL) { istringstream locConstantsStream(buff); locConstantsStream >> time; cout << "TDC Time Offset = " << time << endl; tdc_offsets[counter] = time; counter++; } if (counter != 1152) cout << "Wrong number of TDC entries (" << counter << " != 1152)?" << endl; //Close the pipe gSystem->ClosePipe(locInputFile); sprintf(command, "ccdb dump /BCAL/ADC_timing_offsets:%i:default", run); locInputFile = gSystem->OpenPipe(command, "r"); if(locInputFile == NULL) return 0; //get the first (comment) line char buff[1024]; if(fgets(buff, sizeof(buff), locInputFile) == NULL) return 0; //get the remaining lines counter = 0; while(fgets(buff, sizeof(buff), locInputFile) != NULL) { istringstream locConstantsStream(buff); locConstantsStream >> time; cout << "ADC Time Offset = " << time << endl; adc_offsets[counter] = time; counter++; } if (counter != 1536) cout << "Wrong number of ADC entries (" << counter << " != 1536)?" << endl; //Close the pipe gSystem->ClosePipe(locInputFile); // This stream will be for outputting the results in a format suitable for the CCDB // Will wait to open until needed ofstream adcOffsetFile, tdcOffsetFile; adcOffsetFile.open("ADCOffsetsBCAL.txt"); tdcOffsetFile.open("TDCOffsetsBCAL.txt"); // Declaration of the fit funtion TF1 *f1 = new TF1("f1", "[0]+[1]*x", -200, 200); f1->SetParLimits(0, -20.0, 20.0); f1->SetParLimits(1, 0.85, 1.15); outputFile->cd("ResultOverview"); // Make some histograms to get the distributions of the fit parameters TH1I *h1_c0 = new TH1I("h1_c0", "Distribution of parameter c_{0}", 100, -15, 15); TH1I *h1_c1 = new TH1I("h1_c1", "Distribution of parameter c_{1}", 100, 0.85, 1.15); TH1F *h1_c0_all = new TH1F ("h1_c0_all", "Value of c0; CCDB Index; c0 [cm]", 768, 0.5, 768.5); TH1F *h1_c1_all = new TH1F ("h1_c1_all", "Value of c1; CCDB Index; c1 [cm]", 768, 0.5, 768.5); TH2I *h2_c0_c1 = new TH2I("h2_c0_c1", "c_{1} Vs. c_{0}; c_{0}; c_{1}", 100, -15, 15, 100, 0.85, 1.15); // Fit the global offset histogram to get the per channel global offset double globalOffset[768]; TH1D * selectedBCALOffset = new TH1D("selectedBCALOffset", "Selected Global BCAL Offset; CCDB Index; Offset [ns]", 768, 0.5, 768 + 0.5); TH1I * BCALOffsetDistribution = new TH1I("BCALOffsetDistribution", "Global BCAL Offset; Global Offset [ns]; Entries", 100, -10, 10); thisHist = Get2DHistogram("BCAL_Global_Offsets", "Target Time", "Target Time Minus RF Time Vs. Cell Number"); if(thisHist != NULL) { int nBinsX = thisHist->GetNbinsX(); int nBinsY = thisHist->GetNbinsY(); for (int i = 1 ; i <= nBinsX; i++) { TH1D *projY = thisHist->ProjectionY("temp", i, i); // Scan over the histogram float nsPerBin = (projY->GetBinCenter(projY->GetNbinsX()) - projY->GetBinCenter(1)) / projY->GetNbinsX(); float timeWindow = 0.5; //ns (Full Width) int binWindow = int(timeWindow / nsPerBin); double maxEntries = 0; double maxMean = 0; for (int j = 1 ; j <= projY->GetNbinsX(); j++) { int minBin = j; int maxBin = (j + binWindow) <= projY->GetNbinsX() ? (j + binWindow) : projY->GetNbinsX(); double sum = 0, nEntries = 0; for (int bin = minBin; bin <= maxBin; bin++) { sum += projY->GetBinContent(bin) * projY->GetBinCenter(bin); nEntries += projY->GetBinContent(bin); if (bin == maxBin) { if (nEntries > maxEntries) { maxMean = sum / nEntries; maxEntries = nEntries; } } } } globalOffset[i-1] = maxMean; selectedBCALOffset->SetBinContent(i, maxMean); BCALOffsetDistribution->Fill(maxMean); } } outputFile->cd("Fits"); // Now we want to loop through all available module/layer/sector and try to make a fit of each one for (unsigned int iModule = 1; iModule <=48; iModule++) { for (unsigned int iLayer = 1; iLayer <= 4; iLayer++) { // Only 3 layers with TDCs for (unsigned int iSector = 1; iSector <= 4; iSector++) { int the_cell = (iModule - 1) * 16 + (iLayer - 1) * 4 + iSector; int the_tdc_cell = (iModule - 1) * 12 + (iLayer - 1) * 4 + iSector; // One less layer of TDCs // Format the string to lookup the histogram by name char name[200]; sprintf(name, "Module %.2i Layer %.2i Sector %.2i", iModule, iLayer, iSector); // These histograms are created on the fly in the plugin, so there is a chance that they do not exist, in which case the pointer will be NULL TH2I *h_offsets = Get2DHistogram ("BCAL_TDC_Offsets", "Z Position", name); // Use FitSlicesY routine to extract the mean of each x bin TObjArray ySlices; if (h_offsets != NULL) { h_offsets->RebinX(5); TProfile *profile = h_offsets->ProfileX(); f1->SetParameters(0, 1); // Just out initial guess TFitResultPtr fr = profile->Fit(f1, "SQR"); Int_t fitStatus = fr; if (fitStatus == 0) { double c0 = fr->Parameter(0); double c0_err = fr->ParError(0); double c1 = fr->Parameter(1); double c1_err = fr->ParError(1); if (c0 == 10.0 || c0 == -10.0 || c1 == 0.9 || c1 == 1.1) { cout << "WARNING: Parameter hit limit " << name << endl; } h1_c0->Fill(c0); h1_c1->Fill(c1); h2_c0_c1->Fill(c0,c1); h1_c0_all->SetBinContent(the_cell, c0); h1_c0_all->SetBinError(the_cell, c0_err); h1_c1_all->SetBinContent(the_cell, c1); h1_c1_all->SetBinError(the_cell, c1_err); adcOffsetFile << adc_offsets[(the_cell - 1) * 2] + 0.5 * c0 / C_eff + globalOffset[the_cell] << endl; adcOffsetFile << adc_offsets[ the_cell*2 - 1] - 0.5 * c0 / C_eff + globalOffset[the_cell] << endl; if (iLayer != 4) { tdcOffsetFile << tdc_offsets[(the_tdc_cell - 1) * 2] + 0.5 * c0 / C_eff + globalOffset[the_cell] << endl; tdcOffsetFile << tdc_offsets[the_tdc_cell*2 - 1] - 0.5 * c0 / C_eff + globalOffset[the_cell] << endl; } } else { cout << "WARNING: Fit Status "<< fitStatus << " for Upstream " << name << endl; adcOffsetFile << adc_offsets[(the_cell - 1) * 2] + globalOffset[the_cell] << endl; adcOffsetFile << adc_offsets[the_cell*2 - 1] + globalOffset[the_cell] << endl; if (iLayer != 4) { tdcOffsetFile << tdc_offsets[(the_tdc_cell - 1) * 2] + globalOffset[the_cell] << endl; tdcOffsetFile << tdc_offsets[the_tdc_cell*2 - 1] + globalOffset[the_cell] << endl; } } } else { adcOffsetFile << adc_offsets[ (the_cell-1) * 2] + globalOffset[the_cell] << endl; adcOffsetFile << adc_offsets[ the_cell*2 - 1] + globalOffset[the_cell] << endl; if (iLayer != 4) { tdcOffsetFile << tdc_offsets[(the_tdc_cell -1) * 2] + globalOffset[the_cell] << endl; tdcOffsetFile << tdc_offsets[ the_tdc_cell*2 - 1] + globalOffset[the_cell] << endl; } } } } } adcOffsetFile.close(); tdcOffsetFile.close(); outputFile->Write(); thisFile->Close(); return; }
void ExtractTrackBasedTiming(int runNumber){ TString fileName = Form ("Run%i/TrackBasedTiming.root", runNumber); TString prefix = Form ("Run%i/constants/TrackBasedTiming/",runNumber); TString inputPrefix = Form ("Run%i/constants/TDCADCTiming/",runNumber); thisFile = TFile::Open( fileName , "UPDATE"); if (thisFile == 0) { cout << "Unable to open file " << fileName.Data() << "...Exiting" << endl; return; } //We need the existing constants, The best we can do here is just read them from the file. vector<double> sc_tdc_time_offsets; vector<double> sc_fadc_time_offsets; vector<double> tof_tdc_time_offsets; vector<double> tof_fadc_time_offsets; vector<double> tagm_tdc_time_offsets; vector<double> tagm_fadc_time_offsets; vector<double> tagh_tdc_time_offsets; vector<double> tagh_fadc_time_offsets; double sc_t_base_fadc; double sc_t_base_tdc; double tof_t_base_fadc; double tof_t_base_tdc; double bcal_t_base_fadc; double bcal_t_base_tdc; double tagm_t_base_fadc; double tagm_t_base_tdc; double tagh_t_base_fadc; double tagh_t_base_tdc; double fcal_t_base; double cdc_t_base; ifstream inFile; inFile.open(inputPrefix + "sc_tdc_timing_offsets.txt"); string line; if (inFile.is_open()){ while (getline (inFile, line)){ sc_tdc_time_offsets.push_back(atof(line.data())); } } inFile.close(); ifstream inFile; inFile.open(inputPrefix + "sc_adc_timing_offsets.txt"); string line; if (inFile.is_open()){ while (getline (inFile, line)){ sc_fadc_time_offsets.push_back(atof(line.data())); } } inFile.close(); inFile.open(inputPrefix + "tof_tdc_timing_offsets.txt"); if (inFile.is_open()){ while (getline (inFile, line)){ tof_tdc_time_offsets.push_back(atof(line.data())); } } inFile.close(); inFile.open(inputPrefix + "tof_adc_timing_offsets.txt"); if (inFile.is_open()){ while (getline (inFile, line)){ tof_fadc_time_offsets.push_back(atof(line.data())); } } inFile.close(); inFile.open(inputPrefix + "tagm_tdc_timing_offsets.txt"); if (inFile.is_open()){ while (getline (inFile, line)){ istringstream iss(line); double r, c, offset; while (iss>>r>>c>>offset){ //if (row != 0) continue; tagm_tdc_time_offsets.push_back(offset); } } } inFile.close(); inFile.open(inputPrefix + "tagm_adc_timing_offsets.txt"); if (inFile.is_open()){ while (getline (inFile, line)){ istringstream iss(line); double r, c, offset; while (iss>>r>>c>>offset){ //if (row != 0) continue; tagm_fadc_time_offsets.push_back(offset); } } } inFile.close(); inFile.open(inputPrefix + "tagh_tdc_timing_offsets.txt"); if (inFile.is_open()){ while (getline (inFile, line)){ istringstream iss(line); double counter, offset; while (iss>>counter>>offset){ tagh_tdc_time_offsets.push_back(offset); } } } inFile.close(); inFile.open(inputPrefix + "tagh_adc_timing_offsets.txt"); if (inFile.is_open()){ while (getline (inFile, line)){ istringstream iss(line); double counter, offset; while (iss>>counter>>offset){ tagh_fadc_time_offsets.push_back(offset); } } } inFile.close(); inFile.open(inputPrefix + "tof_base_time.txt"); if (inFile.is_open()){ while (getline (inFile, line)){ istringstream iss(line); iss>>tof_t_base_fadc>>tof_t_base_tdc; } } inFile.close(); inFile.open(inputPrefix + "sc_base_time.txt"); if (inFile.is_open()){ while (getline (inFile, line)){ istringstream iss(line); iss>>sc_t_base_fadc>>sc_t_base_tdc; } } inFile.close(); inFile.open(inputPrefix + "bcal_base_time.txt"); if (inFile.is_open()){ while (getline (inFile, line)){ istringstream iss(line); double adc_offset, tdc_offset; iss>>adc_offset>>tdc_offset; // TDC not used currently bcal_t_base_fadc = adc_offset; bcal_t_base_tdc = tdc_offset; } } inFile.close(); inFile.open(inputPrefix + "tagm_base_time.txt"); if (inFile.is_open()){ while (getline (inFile, line)){ istringstream iss(line); double adc_offset, tdc_offset; iss>>adc_offset>>tdc_offset; // TDC not used currently tagm_t_base_fadc = adc_offset; tagm_t_base_tdc = tdc_offset; } } inFile.close(); inFile.open(inputPrefix + "tagh_base_time.txt"); if (inFile.is_open()){ while (getline (inFile, line)){ istringstream iss(line); double adc_offset, tdc_offset; iss>>adc_offset>>tdc_offset; // TDC not used currently tagh_t_base_fadc = adc_offset; tagh_t_base_tdc = tdc_offset; } } inFile.close(); inFile.open(inputPrefix + "fcal_base_time.txt"); if (inFile.is_open()){ while (getline (inFile, line)){ istringstream iss(line); iss>>fcal_t_base; } } inFile.close(); inFile.open(inputPrefix + "cdc_base_time.txt"); if (inFile.is_open()){ while (getline (inFile, line)){ istringstream iss(line); iss>>cdc_t_base; } } inFile.close(); // Do our final step in the timing alignment with tracking //When the RF is present we can try to simply pick out the correct beam bucket for each of the runs //First just a simple check to see if we have the appropriate data bool useRF = false; double RF_Period = 4.0080161; TH1I *testHist = Get1DHistogram("HLDetectorTiming", "TAGH_TDC_RF_Compare","Counter ID 001"); if (testHist != NULL){ // Not great since we rely on channel 1 working, but can be craftier later. useRF = true; } ofstream outFile; TH2I *thisHist; thisHist = Get2DHistogram("HLDetectorTiming", "TRACKING", "TAGM - SC Target Time"); if (useRF) thisHist = Get2DHistogram("HLDetectorTiming", "TRACKING", "TAGM - RFBunch Time"); if (thisHist != NULL){ //Statistics on these histograms are really quite low we will have to rebin and do some interpolation outFile.open(prefix + "tagm_tdc_timing_offsets.txt", ios::out | ios::trunc); outFile.close(); // clear file outFile.open(prefix + "tagm_adc_timing_offsets.txt", ios::out | ios::trunc); outFile.close(); // clear file int nBinsX = thisHist->GetNbinsX(); int nBinsY = thisHist->GetNbinsY(); TH1D * selectedTAGMOffset = new TH1D("selectedTAGMOffset", "Selected TAGM Offset; Column; Offset [ns]", nBinsX, 0.5, nBinsX + 0.5); TH1I * TAGMOffsetDistribution = new TH1I("TAGMOffsetDistribution", "TAGM Offset; TAGM Offset [ns]; Entries", 500, -250, 250); for (int i = 1 ; i <= nBinsX; i++){ TH1D *projY = thisHist->ProjectionY("temp", i, i); // Scan over the histogram //chose the correct number of bins based on the histogram float nsPerBin = (projY->GetBinCenter(projY->GetNbinsX()) - projY->GetBinCenter(1)) / projY->GetNbinsX(); float timeWindow = 3; //ns (Full Width) int binWindow = int(timeWindow / nsPerBin); double maxEntries = 0; double maxMean = 0; for (int j = 1 ; j <= projY->GetNbinsX();j++){ int minBin = j; int maxBin = (j + binWindow) <= projY->GetNbinsX() ? (j + binWindow) : projY->GetNbinsX(); double sum = 0, nEntries = 0; for (int bin = minBin; bin <= maxBin; bin++){ sum += projY->GetBinContent(bin) * projY->GetBinCenter(bin); nEntries += projY->GetBinContent(bin); if (bin == maxBin){ if (nEntries > maxEntries) { maxMean = sum / nEntries; maxEntries = nEntries; } } } } //In the case there is RF, our job is to pick just the number of the correct beam bunch, so that's really all we need. if(useRF) { int beamBucket = int((maxMean / RF_Period) + 0.5); // +0.5 to handle rounding correctly selectedTAGMOffset->SetBinContent(i, beamBucket); TAGMOffsetDistribution->Fill(beamBucket); } else{ selectedTAGMOffset->SetBinContent(i, maxMean); TAGMOffsetDistribution->Fill(maxMean); } } /* if (!useRF){ //TFitResultPtr fr1 = selectedTAGMOffset->Fit("pol1", "SQ", "", 0.5, nBinsX + 0.5); TFitResultPtr fr1 = selectedTAGMOffset->Fit("pol1", "SQ", "", 5, 50); for (int i = 1 ; i <= nBinsX; i++){ double x0 = fr1->Parameter(0); double x1 = fr1->Parameter(1); //double x2 = fr1->Parameter(2); //double fitResult = x0 + i*x1 + i*i*x2; double fitResult = x0 + i*x1; double outlierCut = 20; double valueToUse = selectedTAGMOffset->GetBinContent(i); if (fabs(selectedTAGMOffset->GetBinContent(i) - fitResult) > outlierCut && valueToUse != 0.0){ valueToUse = fitResult; } selectedTAGMOffset->SetBinContent(i, valueToUse); if (valueToUse != 0 ) TAGMOffsetDistribution->Fill(valueToUse); } } */ double meanOffset = TAGMOffsetDistribution->GetMean(); // This might be in units of beam bunches, so we need to convert if (useRF) meanOffset *= RF_Period; /* for (int i = 1 ; i <= nBinsX; i++){ double valueToUse = selectedTAGMOffset->GetBinContent(i); if (useRF) valueToUse *= RF_Period; if (valueToUse == 0) valueToUse = meanOffset; outFile.open(prefix + "tagm_tdc_timing_offsets.txt", ios::out | ios::app); outFile << "0 " << i << " " << valueToUse + tagm_tdc_time_offsets[i-1] - meanOffset<< endl; if (i == 7 || i == 25 || i == 79 || i == 97){ for(int j = 1; j <= 5; j++){ outFile << j << " " << i << " " << valueToUse + tagm_tdc_time_offsets[i-1] - meanOffset<< endl; } } outFile.close(); // Apply the same shift to the adc offsets outFile.open(prefix + "tagm_adc_timing_offsets.txt", ios::out | ios::app); outFile << "0 " << i << " " << valueToUse + tagm_fadc_time_offsets[i-1] - meanOffset<< endl; if (i == 7 || i == 25 || i == 79 || i == 97){ for(int j = 1; j <= 5; j++){ outFile << j << " " << i << " " << valueToUse + tagm_fadc_time_offsets[i-1] - meanOffset<< endl; } } outFile.close(); } */ outFile.open(prefix + "tagm_adc_timing_offsets.txt", ios::out); //for (int i = 1 ; i <= nBinsX; i++){ // Loop over rows for (unsigned int column = 1; column <= 102; column++){ int index = GetCCDBIndexTAGM(column, 0); double valueToUse = selectedTAGMOffset->GetBinContent(index); if (useRF) valueToUse *= RF_Period; if (valueToUse == 0) valueToUse = meanOffset; outFile << "0 " << column << " " << valueToUse + tagm_fadc_time_offsets[index-1] - meanOffset<< endl; if (column == 9 || column == 27 || column == 81 || column == 99){ for (unsigned int row = 1; row <= 5; row++){ index = GetCCDBIndexTAGM(column, row); valueToUse = selectedTAGMOffset->GetBinContent(index); if (useRF) valueToUse *= RF_Period; if (valueToUse == 0) valueToUse = meanOffset; outFile << row << " " << column << " " << valueToUse + tagm_fadc_time_offsets[index-1] - meanOffset<< endl; } } } outFile.close(); outFile.open(prefix + "tagm_tdc_timing_offsets.txt", ios::out); //for (int i = 1 ; i <= nBinsX; i++){ // Loop over rows for (unsigned int column = 1; column <= 102; column++){ int index = GetCCDBIndexTAGM(column, 0); double valueToUse = selectedTAGMOffset->GetBinContent(index); if (useRF) valueToUse *= RF_Period; if (valueToUse == 0) valueToUse = meanOffset; outFile << "0 " << column << " " << valueToUse + tagm_tdc_time_offsets[index-1] - meanOffset << endl; if (column == 9 || column == 27 || column == 81 || column == 99){ for (unsigned int row = 1; row <= 5; row++){ index = GetCCDBIndexTAGM(column, row); valueToUse = selectedTAGMOffset->GetBinContent(index); if (useRF) valueToUse *= RF_Period; if (valueToUse == 0) valueToUse = meanOffset; outFile << row << " " << column << " " << valueToUse + tagm_tdc_time_offsets[index-1] - meanOffset << endl; } } } outFile.close(); outFile.open(prefix + "tagm_base_time.txt", ios::out); outFile << tagm_t_base_fadc - meanOffset << " " << tagm_t_base_tdc - meanOffset << endl; outFile.close(); } thisHist = Get2DHistogram("HLDetectorTiming", "TRACKING", "TAGH - SC Target Time"); if (useRF) thisHist = Get2DHistogram("HLDetectorTiming", "TRACKING", "TAGH - RFBunch Time"); if(thisHist != NULL){ outFile.open(prefix + "tagh_tdc_timing_offsets.txt", ios::out | ios::trunc); outFile.close(); // clear file outFile.open(prefix + "tagh_adc_timing_offsets.txt", ios::out | ios::trunc); outFile.close(); // clear file int nBinsX = thisHist->GetNbinsX(); int nBinsY = thisHist->GetNbinsY(); TH1D * selectedTAGHOffset = new TH1D("selectedTAGHOffset", "Selected TAGH Offset; ID; Offset [ns]", nBinsX, 0.5, nBinsX + 0.5); TH1I * TAGHOffsetDistribution = new TH1I("TAGHOffsetDistribution", "TAGH Offset; TAGH Offset [ns]; Entries", 500, -250, 250); for (int i = 1 ; i <= nBinsX; i++){ TH1D *projY = thisHist->ProjectionY("temp", i, i); // Scan over the histogram //chose the correct number of bins based on the histogram float nsPerBin = (projY->GetBinCenter(projY->GetNbinsX()) - projY->GetBinCenter(1)) / projY->GetNbinsX(); float timeWindow = 2; //ns (Full Width) int binWindow = int(timeWindow / nsPerBin); double maxEntries = 0; double maxMean = 0; for (int j = 1 ; j <= projY->GetNbinsX();j++){ int minBin = j; int maxBin = (j + binWindow) <= projY->GetNbinsX() ? (j + binWindow) : projY->GetNbinsX(); double sum = 0; double nEntries = 0; for (int bin = minBin; bin <= maxBin; bin++){ sum += projY->GetBinContent(bin) * projY->GetBinCenter(bin); nEntries += projY->GetBinContent(bin); if (bin == maxBin){ if (nEntries > maxEntries){ maxMean = sum / nEntries; maxEntries = nEntries; } } } } if(useRF) { int beamBucket = int((maxMean / RF_Period) + 0.5); // +0.5 to handle rounding correctly selectedTAGHOffset->SetBinContent(i, beamBucket); TAGHOffsetDistribution->Fill(beamBucket); } else{ selectedTAGHOffset->SetBinContent(i, maxMean); } /* outFile.open("tagh_tdc_timing_offsets.txt", ios::out | ios::app); outFile << i << " " << maxMean + tagh_tdc_time_offsets[i] << endl; outFile.close(); outFile.open("tagh_adc_timing_offsets.txt", ios::out | ios::app); outFile << i << " " << maxMean + tagh_fadc_time_offsets[i] << endl; outFile.close(); */ } // Fit 1D histogram. If value is far from the fit use the fitted value // Two behaviors above and below microscope // This isn't working well, so removing... /* TFitResultPtr fr1 = selectedTAGHOffset->Fit("pol2", "SQ", "", 0.5, 131.5); TFitResultPtr fr2 = selectedTAGHOffset->Fit("pol2", "SQ", "", 182.5, 274.5); for (int i = 1 ; i <= nBinsX; i++){ double fitResult = 0.0; if (i < 150){ double x0 = fr1->Parameter(0); double x1 = fr1->Parameter(1); double x2 = fr1->Parameter(2); fitResult = x0 + i*x1 + i*i*x2; } else{ double x0 = fr2->Parameter(0); double x1 = fr2->Parameter(1); double x2 = fr2->Parameter(2); fitResult = x0 + i*x1 + i*i*x2; } double outlierCut = 7; double valueToUse = selectedTAGHOffset->GetBinContent(i); if (fabs(selectedTAGHOffset->GetBinContent(i) - fitResult) > outlierCut && valueToUse != 0.0){ valueToUse = fitResult; } selectedTAGHOffset->SetBinContent(i, valueToUse); if(valueToUse != 0) TAGHOffsetDistribution->Fill(valueToUse); } */ double meanOffset = TAGHOffsetDistribution->GetMean(); if (useRF) meanOffset *= RF_Period; for (int i = 1 ; i <= nBinsX; i++){ valueToUse = selectedTAGHOffset->GetBinContent(i); if (useRF) valueToUse *= RF_Period; if (valueToUse == 0) valueToUse = meanOffset; outFile.open(prefix + "tagh_tdc_timing_offsets.txt", ios::out | ios::app); outFile << i << " " << valueToUse + tagh_tdc_time_offsets[i-1] - meanOffset << endl; outFile.close(); outFile.open(prefix + "tagh_adc_timing_offsets.txt", ios::out | ios::app); outFile << i << " " << valueToUse + tagh_fadc_time_offsets[i-1] - meanOffset << endl; outFile.close(); } outFile.open(prefix + "tagh_base_time.txt", ios::out); outFile << tagh_t_base_fadc - meanOffset << " " << tagh_t_base_tdc - meanOffset << endl; outFile.close(); } // We can use the RF time to calibrate the SC time (Experimental for now) double meanSCOffset = 0.0; // In case we change the time of the SC, we need this in this scope if(useRF){ TH1F * selectedSCSectorOffset = new TH1F("selectedSCSectorOffset", "Selected TDC-RF offset;Sector; Time", 30, 0.5, 30.5); TH1F * selectedSCSectorOffsetDistribution = new TH1F("selectedSCSectorOffsetDistribution", "Selected TDC-RF offset;Time;Entries", 100, -3.0, 3.0); TF1* f = new TF1("f","pol0(0)+gaus(1)", -3.0, 3.0); for (int sector = 1; sector <= 30; sector++){ TH1I *scRFHist = Get1DHistogram("HLDetectorTiming", "SC_Target_RF_Compare", Form("Sector %.2i", sector)); if (scRFHist == NULL) continue; //Do the fit TFitResultPtr fr = scRFHist->Fit("pol0", "SQ", "", -2, 2); double p0 = fr->Parameter(0); f->FixParameter(0,p0); f->SetParLimits(2, -2, 2); f->SetParLimits(3, 0, 2); f->SetParameter(1, 10); f->SetParameter(2, scRFHist->GetBinCenter(scRFHist->GetMaximumBin())); f->SetParameter(3, 0); fr = scRFHist->Fit(f, "SQ", "", -2, 2); double SCOffset = fr->Parameter(2); selectedSCSectorOffset->SetBinContent(sector, SCOffset); selectedSCSectorOffsetDistribution->Fill(SCOffset); } // Now write out the offsets meanSCOffset = selectedSCSectorOffsetDistribution->GetMean(); outFile.open(prefix + "sc_tdc_timing_offsets.txt"); for (int sector = 1; sector <= 30; sector++){ outFile << sc_tdc_time_offsets[sector-1] + selectedSCSectorOffset->GetBinContent(sector) - meanSCOffset << endl; } outFile.close(); outFile.open(prefix + "sc_adc_timing_offsets.txt"); for (int sector = 1; sector <= 30; sector++){ outFile << sc_fadc_time_offsets[sector-1] + selectedSCSectorOffset->GetBinContent(sector) - meanSCOffset << endl; } outFile.close(); outFile.open(prefix + "sc_base_time.txt"); outFile << sc_t_base_fadc - meanSCOffset << " " << sc_t_base_tdc - meanSCOffset << endl; outFile.close(); } TH1I *this1DHist = Get1DHistogram("HLDetectorTiming", "TRACKING", "TOF - SC Target Time"); if(this1DHist != NULL){ //Gaussian Double_t maximum = this1DHist->GetBinCenter(this1DHist->GetMaximumBin()); TFitResultPtr fr = this1DHist->Fit("gaus", "S", "", maximum - 1.5, maximum + 1.5); float mean = fr->Parameter(1); outFile.open(prefix + "tof_base_time.txt"); outFile << tof_t_base_fadc - mean - meanSCOffset<< " " << tof_t_base_tdc - mean - meanSCOffset<< endl; outFile.close(); } this1DHist = Get1DHistogram("HLDetectorTiming", "TRACKING", "BCAL - SC Target Time"); if(this1DHist != NULL){ //Gaussian Double_t maximum = this1DHist->GetBinCenter(this1DHist->GetMaximumBin()); TFitResultPtr fr = this1DHist->Fit("gaus", "S", "", maximum - 5, maximum + 5); float mean = fr->Parameter(1); outFile.open(prefix + "bcal_base_time.txt"); outFile << bcal_t_base_fadc - mean - meanSCOffset << " " << bcal_t_base_tdc - mean - meanSCOffset << endl; // TDC info not used outFile.close(); } this1DHist = Get1DHistogram("HLDetectorTiming", "TRACKING", "FCAL - SC Target Time"); if(this1DHist != NULL){ //Gaussian Double_t maximum = this1DHist->GetBinCenter(this1DHist->GetMaximumBin()); TFitResultPtr fr = this1DHist->Fit("gaus", "S", "", maximum - 5, maximum + 5); float mean = fr->Parameter(1); outFile.open(prefix + "fcal_base_time.txt"); outFile << fcal_t_base - mean - meanSCOffset<< endl; outFile.close(); } this1DHist = Get1DHistogram("HLDetectorTiming", "TRACKING", "Earliest CDC Time Minus Matched SC Time"); if(this1DHist != NULL){ //Gaussian Double_t maximum = this1DHist->GetBinCenter(this1DHist->GetMaximumBin()); TFitResultPtr fr = this1DHist->Fit("gaus", "S", "", maximum - 15, maximum + 10); float mean = fr->Parameter(1); outFile.open(prefix + "cdc_base_time.txt"); outFile << cdc_t_base - mean - meanSCOffset << endl; outFile.close(); } thisFile->Write(); return; }
// Do the extraction of the actual constants void ExtractCDCDeformation(TString filename = "hd_root.root"){ // Open our input and output file thisFile = TFile::Open(filename); TFile *outputFile = TFile::Open("CDCDeformation_Results.root", "RECREATE"); // Check to make sure it is open if (thisFile == 0) { cout << "Unable to open file " << filename.Data() << "...Exiting" << endl; return; } // This stream will be for outputting the results in a format suitable for the CCDB // Will wait to open until needed ofstream textFile; textFile.open("CDC_Deformation.txt"); // We want to display the direction of the shift as well as the magnitude in the "CDC view" // Let's make it happen int straw_offset[29] = {0,0,42,84,138,192,258,324,404,484,577,670,776,882,1005,1128,1263,1398,1544,1690,1848,2006,2176,2346,2528,2710,2907,3104,3313}; int Nstraws[28] = {42, 42, 54, 54, 66, 66, 80, 80, 93, 93, 106, 106, 123, 123, 135, 135, 146, 146, 158, 158, 170, 170, 182, 182, 197, 197, 209, 209}; double radius[28] = {10.72134, 12.08024, 13.7795, 15.14602, 18.71726, 20.2438, 22.01672, 23.50008, 25.15616, 26.61158, 28.33624, 29.77388, 31.3817, 32.75838, 34.43478, 35.81146, 38.28542, 39.7002, 41.31564, 42.73042, 44.34078, 45.75302, 47.36084, 48.77054, 50.37582, 51.76012, 53.36286, 54.74716}; double phi[28] = {0, 0.074707844, 0.038166294, 0.096247609, 0.05966371, 0.012001551, 0.040721951, 0.001334527, 0.014963808, 0.048683644, 0.002092645, 0.031681749, 0.040719354, 0.015197341, 0.006786058, 0.030005892, 0.019704045, -0.001782064, -0.001306618, 0.018592421, 0.003686784, 0.022132975, 0.019600866, 0.002343723, 0.021301449, 0.005348855, 0.005997358, 0.021018761}; TH2D * Amplitude_view[29]; TH2D * Direction_view[29]; TH2D * Vertical_view[29]; TH2D * Horizontal_view[29]; outputFile->mkdir("PerRing"); outputFile->cd("PerRing"); for(unsigned int iring=0; iring<28; iring++){ double r_start = radius[iring] - 0.8; double r_end = radius[iring] + 0.8; double phi_start = phi[iring]; double phi_end = phi_start + TMath::TwoPi(); char hname[256]; sprintf(hname, "Amplitude_view_ring[%d]", iring+1); Amplitude_view[iring+1] = new TH2D(hname, "", Nstraws[iring], phi_start, phi_end, 1, r_start, r_end); sprintf(hname, "Direction_view_ring[%d]", iring+1); Direction_view[iring+1] = new TH2D(hname, "", Nstraws[iring], phi_start, phi_end, 1, r_start, r_end); sprintf(hname, "Vertical_view_ring[%d]", iring+1); Vertical_view[iring+1] = new TH2D(hname, "", Nstraws[iring], phi_start, phi_end, 1, r_start, r_end); sprintf(hname, "Horizontal_view_ring[%d]", iring+1); Horizontal_view[iring+1] = new TH2D(hname, "", Nstraws[iring], phi_start, phi_end, 1, r_start, r_end); } //Fit function for TF1 *f1 = new TF1("f1", "[0] + [1] * TMath::Cos(x + [2])", -3.14, 3.14); f1->SetParLimits(0, 0.5, 1.0); f1->SetParLimits(1, 0.0, 0.35); //f1->SetParLimits(2, -3.14, 3.14); f1->SetParameters(0.78, 0.0, 0.0); outputFile->cd(); outputFile->mkdir("FitParameters"); outputFile->cd("FitParameters"); // Make some histograms to get the distributions of the fit parameters TH1I *h1_c0 = new TH1I("h1_c0", "Distribution of Constant", 100, 0.5, 1.0); TH1I *h1_c1 = new TH1I("h1_c1", "Distribution of Amplitude", 100, 0.0, 0.35); TH1I *h1_c2 = new TH1I("h1_c2", "Direction of Longest Drift Time", 100, -3.14, 3.14); TH1F *h1_c2_weighted = new TH1F("h1_c2_weighted", "Distribution of Direction weighted by amplitude", 100, -3.14, 3.14); TH2I *h2_c0_c1 = new TH2I("h2_c0_c1", "c_{1} Vs. c_{0}; c_{0}; c_{1}", 100, 0.5, 1.0, 100, 0, 0.35); TH2I *h2_c0_c2 = new TH2I("h2_c0_c2", "c_{2} Vs. c_{0}; c_{0}; c_{2}", 100, 0.5, 1.0, 100, -10, 10); TH2I *h2_c1_c2 = new TH2I("h2_c1_c2", "c_{2} Vs. c_{1}; c_{1}; c_{2}", 100, 0.0, 0.35, 100, -10, 10); outputFile->cd(); outputFile->mkdir("Fits"); outputFile->cd("Fits"); // Now we want to loop through all available module/layer/sector and try to make a fit of each one int ring = 1, straw = 1; while (ring <= 28){ cout << "Entering Fit " << endl; char folder[100]; sprintf(folder, "Ring %.2i", ring); char strawname[100]; sprintf(strawname,"Straw %.3i Predicted Drift Distance Vs phi_DOCA", straw); TH2I *thisStrawHistogram = Get2DHistogram("CDC_Cosmic_Per_Straw",folder,strawname); if (thisStrawHistogram != NULL) { // Now to do our fits. This time we know there are 16 bins. double percentile95[16], percentile97[16], percentile99[16]; // Location of 95, 97,and 99th percentile bins double binCenter[16]; char name[100]; sprintf(name,"Ring %.2i Straw %.3i", ring, straw); TH1D *extractedPoints = new TH1D(name, name, 16, -3.14, 3.14); for (int i = 1; i <= thisStrawHistogram->GetNbinsX() ; i++){ TH1D *projY = thisStrawHistogram->ProjectionY(" ", i, i); binCenter[i-1] = thisStrawHistogram->GetXaxis()->GetBinCenter(i); int nbins = projY->GetNbinsX(); //Get the total nubmer of entries int nEntries = projY->GetEntries(); if (nEntries == 0) continue; double errorFraction = TMath::Sqrt(nEntries) / nEntries; double perc95 = 0.95*nEntries, perc97 = 0.97 * nEntries, perc99 = 0.99 * nEntries; //Accumulate from the beginning to get total, mark 95, 97, 99% location int total = 0; for (int j = 0; j <= nbins; j++){ total += projY->GetBinContent(j); if (total > perc99) percentile99[i-1] = projY->GetBinCenter(j); else if (total > perc97) { percentile97[i-1] = projY->GetBinCenter(j); extractedPoints->SetBinContent(i, projY->GetBinCenter(j)); extractedPoints->SetBinError(i, errorFraction * projY->GetBinCenter(j)); } else if (total > perc95) percentile95[i-1] = projY->GetBinCenter(j); } } f1->SetParameters(0.78, 0.0, 0.0); TFitResultPtr fr = extractedPoints->Fit(f1, "SR"); Int_t fitStatus = fr; if (fitStatus == 0){ double c0 = fr->Parameter(0); double c1 = fr->Parameter(1); double c2 = fr->Parameter(2); // Move c2 to fit on our range while (c2 > TMath::Pi()) c2 -= 2 * TMath::Pi(); while (c2 < -1* TMath::Pi()) c2 += 2 * TMath::Pi(); h1_c0->Fill(c0); h1_c1->Fill(c1); h1_c2->Fill(-1*c2); h1_c2_weighted->Fill(-1*c2,c1); h2_c0_c1->Fill(c0,c1); h2_c0_c2->Fill(c0,c2); h2_c1_c2->Fill(c1,c2); Amplitude_view[ring]->SetBinContent(straw,1,c1); Direction_view[ring]->SetBinContent(straw,1,-1*c2); Vertical_view[ring]->SetBinContent(straw,1,c1*TMath::Sin(-1*c2)); Horizontal_view[ring]->SetBinContent(straw,1,c1*TMath::Cos(-1*c2)); textFile << c1 << " " << c2 << endl; } else { cout << "WARNING: Fit Status "<< fitStatus << " for ring " << ring << " straw " << straw << endl; textFile << "0.0 0.0" << endl; } } else{ textFile << "0.0 0.0" << endl; } // On to the next one straw++; if(straw > Nstraws[ring-1]){ straw = 1; ring++; } } outputFile->cd(); outputFile->mkdir("2D"); outputFile->cd("2D"); TCanvas *c_Amplitude = Plot2DCDC(Amplitude_view,"c_Amplitude", "Amplitude of Sinusoid", 0.0, 0.3); TCanvas *c_Direction = Plot2DCDC(Direction_view,"c_Direction", "Direction of #delta", -3.14, 3.14); TCanvas *c_Vertical = Plot2DCDC(Vertical_view,"c_Vertical", "Vertical Projection of Delta", -0.3, 0.3); TCanvas *c_Horizontal = Plot2DCDC(Horizontal_view,"c_Horizontal", "Horizontal Projection of Delta", -0.3, 0.3); c_Amplitude->Write(); c_Direction->Write(); c_Horizontal->Write(); c_Vertical->Write(); cout << "Closing Files..." << endl; outputFile->Write(); thisFile->Close(); textFile.close(); return; }