void ExtractTrackBasedTiming(TString fileName = "hd_root.root", int runNumber = 10390, TString variation = "default", bool verbose = false,TString prefix = ""){ // set "prefix" in case you want to ship the txt files elsewhere... cout << "Performing Track Matched timing fits for File: " << fileName.Data() << " Run: " << runNumber << " Variation: " << variation.Data() << endl; ExtractTrackBasedTimingNS::thisFile = TFile::Open( fileName , "UPDATE"); if (ExtractTrackBasedTimingNS::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; vector<double> tagh_counter_quality; double sc_t_base_fadc, sc_t_base_tdc; double tof_t_base_fadc, tof_t_base_tdc; double bcal_t_base_fadc, bcal_t_base_tdc; double tagm_t_base_fadc, tagm_t_base_tdc; double tagh_t_base_fadc, tagh_t_base_tdc; double fdc_t_base_fadc, fdc_t_base_tdc; double fcal_t_base; double cdc_t_base; double RF_Period; cout << "Grabbing CCDB constants..." << endl; // Base times GetCCDBConstants1("/CDC/base_time_offset" ,runNumber, variation, cdc_t_base); GetCCDBConstants1("/FCAL/base_time_offset",runNumber, variation, fcal_t_base); GetCCDBConstants1("/PHOTON_BEAM/RF/beam_period",runNumber, variation, RF_Period); GetCCDBConstants2("/FDC/base_time_offset" ,runNumber, variation, fdc_t_base_fadc, fdc_t_base_tdc); GetCCDBConstants2("/BCAL/base_time_offset" ,runNumber, variation, bcal_t_base_fadc, bcal_t_base_tdc); GetCCDBConstants2("/PHOTON_BEAM/microscope/base_time_offset" ,runNumber, variation, tagm_t_base_fadc, tagm_t_base_tdc); GetCCDBConstants2("/PHOTON_BEAM/hodoscope/base_time_offset" ,runNumber, variation, tagh_t_base_fadc, tagh_t_base_tdc); GetCCDBConstants2("/START_COUNTER/base_time_offset" ,runNumber, variation, sc_t_base_fadc, sc_t_base_tdc); GetCCDBConstants2("/TOF/base_time_offset" ,runNumber, variation, tof_t_base_fadc, tof_t_base_tdc); // Per channel //GetCCDBConstants("/BCAL/TDC_offsets" ,runNumber, variation, bcal_tdc_offsets); //GetCCDBConstants("/FCAL/timing_offsets" ,runNumber, variation, fcal_adc_offsets); GetCCDBConstants("/START_COUNTER/adc_timing_offsets" ,runNumber, variation, sc_fadc_time_offsets); GetCCDBConstants("/START_COUNTER/tdc_timing_offsets" ,runNumber, variation, sc_tdc_time_offsets); GetCCDBConstants("/PHOTON_BEAM/microscope/fadc_time_offsets" ,runNumber, variation, tagm_fadc_time_offsets,3);// Interested in 3rd column GetCCDBConstants("/PHOTON_BEAM/microscope/tdc_time_offsets" ,runNumber, variation, tagm_tdc_time_offsets,3); GetCCDBConstants("/PHOTON_BEAM/hodoscope/fadc_time_offsets" ,runNumber, variation, tagh_fadc_time_offsets,2);// Interested in 2nd column GetCCDBConstants("/PHOTON_BEAM/hodoscope/tdc_time_offsets" ,runNumber, variation, tagh_tdc_time_offsets,2); GetCCDBConstants("/PHOTON_BEAM/hodoscope/counter_quality" ,runNumber, variation, tagh_counter_quality,2); GetCCDBConstants("/TOF/adc_timing_offsets",runNumber, variation, tof_fadc_time_offsets); GetCCDBConstants("/TOF/timing_offsets",runNumber, variation, tof_tdc_time_offsets); cout << "CDC base times = " << cdc_t_base << endl; cout << "FCAL base times = " << fcal_t_base << endl; cout << "FDC base times = " << fdc_t_base_fadc << ", " << fdc_t_base_tdc << endl; cout << "BCAL base times = " << bcal_t_base_fadc << ", " << bcal_t_base_tdc << endl; cout << "SC base times = " << sc_t_base_fadc << ", " << sc_t_base_tdc << endl; cout << "TOF base times = " << tof_t_base_fadc << ", " << tof_t_base_tdc << endl; cout << "TAGH base times = " << tagh_t_base_fadc << ", " << tagh_t_base_tdc << endl; cout << "TAGM base times = " << tagm_t_base_fadc << ", " << tagm_t_base_tdc << endl; cout << endl; cout << "RF_Period = " << RF_Period << endl; cout << endl; cout << "Done grabbing CCDB constants...Entering fits..." << endl; // 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; TH1I *testHist = ExtractTrackBasedTimingNS::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. cout << "Using RF Times for Calibration" << endl; useRF = true; } ofstream outFile; TH2I *thisHist; thisHist = ExtractTrackBasedTimingNS::Get2DHistogram("HLDetectorTiming", "TRACKING", "TAGM - SC Target Time"); if (useRF) thisHist = ExtractTrackBasedTimingNS::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); } } double meanOffset = TAGMOffsetDistribution->GetMean(); // This might be in units of beam bunches, so we need to convert if (useRF) meanOffset *= RF_Period; if (verbose) { cout << "Dumping TAGM results...\n=======================================" << endl; cout << "TAGM mean Offset = " << meanOffset << endl; cout << "fADC Offsets" << endl; } outFile.open(prefix + "tagm_adc_timing_offsets.txt", ios::out); //for (int i = 1 ; i <= nBinsX; i++){ // Loop over rows if (verbose) cout << "Column\tRow\tvalueToUse\toldValue\tmeanOffset\tTotal" << endl; 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 (verbose) printf("0\t%i\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\n", column, valueToUse, tagm_fadc_time_offsets[index-1], meanOffset, valueToUse + tagm_fadc_time_offsets[index-1] - meanOffset); 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; if (verbose) printf("%i\t%i\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\n", row, column, valueToUse, tagm_fadc_time_offsets[index-1], meanOffset, valueToUse + tagm_fadc_time_offsets[index-1] - meanOffset); } } } outFile.close(); if (verbose) { cout << "TDC Offsets" << endl; cout << "Column\tRow\tvalueToUse\toldValue\tmeanOffset\tTotal" << endl; } 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 (verbose) printf("0\t%i\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\n", column, valueToUse, tagm_tdc_time_offsets[index-1], meanOffset, valueToUse + tagm_tdc_time_offsets[index-1] - meanOffset); 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; if (verbose) printf("%i\t%i\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\n", row, column, valueToUse, tagm_tdc_time_offsets[index-1], meanOffset, valueToUse + tagm_tdc_time_offsets[index-1] - meanOffset); } } } outFile.close(); outFile.open(prefix + "tagm_base_time.txt", ios::out); if (verbose) { printf("TAGM ADC Base = %f - (%f) = %f\n", tagm_t_base_fadc, meanOffset, tagm_t_base_fadc - meanOffset); printf("TAGM TDC Base = %f - (%f) = %f\n", tagm_t_base_tdc, meanOffset, tagm_t_base_tdc - meanOffset); } outFile << tagm_t_base_fadc - meanOffset << " " << tagm_t_base_tdc - meanOffset << endl; outFile.close(); } thisHist = ExtractTrackBasedTimingNS::Get2DHistogram("HLDetectorTiming", "TRACKING", "TAGH - SC Target Time"); if (useRF) thisHist = ExtractTrackBasedTimingNS::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 // Setup histogram for determining the most probable change in offset for each F1TDC slot // This is needed to account for the occasional uniform shift in offsets of the 32 counters in a slot const int NtdcSlots = 8; TH1I * tdcDist[NtdcSlots]; for (int i = 1; i <= NtdcSlots; i++) { stringstream ss; ss << i; TString s = ss.str(); double range = 500.0; double width = 0.1; int Nbins = range/width; double low = -0.5*range - 0.5*width; double high = 0.5*range - 0.5*width; tdcDist[i-1] = new TH1I("TAGHOffsetDistribution_"+s, "TAGH Offset (slot "+s+"); TAGH Offset [ns]; Entries", Nbins, low, high); } int nBinsX = thisHist->GetNbinsX(); TH1D * selectedTAGHOffset = new TH1D("selectedTAGHOffset", "Selected TAGH Offset; ID; Offset [ns]", nBinsX, 0.5, nBinsX + 0.5); for (int i = 1 ; i <= nBinsX; i++) { TH1D *projY = thisHist->ProjectionY("temp", i, i); // Scan over histogram to find mean offset in timeWindow with largest integral // Choose the correct number of bins based on the histogram double nsPerBin = (projY->GetBinCenter(projY->GetNbinsX()) - projY->GetBinCenter(1)) / projY->GetNbinsX(); double timeWindow = 2.0; // 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 (tagh_counter_quality[i-1] == 0.0) { selectedTAGHOffset->SetBinContent(i, 0); continue; } int tdc_slot = GetF1TDCslotTAGH(i); if (useRF) { int beamBucket; if (maxMean >= 0) beamBucket = int((maxMean / RF_Period) + 0.5); // +0.5 to handle rounding correctly else beamBucket = int((maxMean / RF_Period) - 0.5); selectedTAGHOffset->SetBinContent(i, beamBucket); if (maxEntries != 0.0) tdcDist[tdc_slot - 1]->Fill(beamBucket); } else { selectedTAGHOffset->SetBinContent(i, maxMean); if (maxEntries != 0.0) tdcDist[tdc_slot - 1]->Fill(maxMean); } } // Most probable change in offset or beam bucket per F1TDC slot double mpDelta[NtdcSlots]; for (int i = 1; i <= NtdcSlots; i++) { int mpBin = tdcDist[i-1]->GetMaximumBin(); mpDelta[i-1] = (mpBin > 0) ? tdcDist[i-1]->GetBinCenter(mpBin) : 0.0; if (useRF) mpDelta[i-1] *= RF_Period; if (verbose) { cout << "TAGH most probable Offset = " << i << ", " << mpDelta[i-1] << endl; } } if (verbose) { cout << "Dumping TAGH results...\n=======================================" << endl; cout << "Type\tChannel\tvalueToUse\toldValue\tmpDelta\tTotal" << endl; } double limit = 2.5; // ns double ccdb_sum = 0.0; for (int i = 1; i <= nBinsX; i++) ccdb_sum += tagh_tdc_time_offsets[i-1]; double c1_tdcOffset = 0.0; outFile.open(prefix + "tagh_tdc_timing_offsets.txt"); for (int i = 1; i <= nBinsX; i++) { if (tagh_counter_quality[i-1] == 0.0) { outFile << i << " " << 0 << endl; continue; } int tdc_slot = GetF1TDCslotTAGH(i); double delta = selectedTAGHOffset->GetBinContent(i); if (useRF) delta *= RF_Period; if (ccdb_sum > 0.0 && fabs(delta - mpDelta[tdc_slot-1]) > limit) { delta = mpDelta[tdc_slot-1]; } double ccdb = tagh_tdc_time_offsets[i-1]; double offset = ccdb + delta; if (i == 1) c1_tdcOffset = offset; offset -= c1_tdcOffset; outFile << i << " " << offset << endl; if (verbose) printf("TDC\t%i\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\n", i, delta, ccdb, mpDelta[tdc_slot-1], offset); } outFile.close(); ccdb_sum = 0.0; for (int i = 1; i <= nBinsX; i++) ccdb_sum += tagh_fadc_time_offsets[i-1]; double c1_adcOffset = 0.0; outFile.open(prefix + "tagh_adc_timing_offsets.txt"); for (int i = 1; i <= nBinsX; i++) { if (tagh_counter_quality[i-1] == 0.0) { outFile << i << " " << 0 << endl; continue; } int tdc_slot = GetF1TDCslotTAGH(i); double delta = selectedTAGHOffset->GetBinContent(i); if (useRF) delta *= RF_Period; if (ccdb_sum > 0.0 && fabs(delta - mpDelta[tdc_slot-1]) > limit) { delta = mpDelta[tdc_slot-1]; } double ccdb = tagh_fadc_time_offsets[i-1]; double offset = ccdb + delta; if (i == 1) c1_adcOffset = offset; offset -= c1_adcOffset; outFile << i << " " << offset << endl; if (verbose) printf("ADC\t%i\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\n", i, delta, ccdb, mpDelta[tdc_slot-1], offset); } outFile.close(); outFile.open(prefix + "tagh_base_time.txt"); outFile << tagh_t_base_fadc - c1_adcOffset << " " << tagh_t_base_tdc - c1_tdcOffset << endl; if (verbose) { printf("TAGH ADC Base = %f - (%f) = %f\n", tagh_t_base_fadc, c1_adcOffset, tagh_t_base_fadc - c1_adcOffset); printf("TAGH TDC Base = %f - (%f) = %f\n", tagh_t_base_tdc, c1_tdcOffset, tagh_t_base_tdc - c1_tdcOffset); } 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 = ExtractTrackBasedTimingNS::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(); if (verbose){ cout << "Dumping SC results...\n=======================================" << endl; cout << "SC mean Offset = " << meanSCOffset << endl; cout << "TDC Offsets" << endl; cout << "Sector\toldValue\tValueToUse\tmeanOffset\tTotal" << endl; } 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; if (verbose) printf("%i\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\n",sector, sc_tdc_time_offsets[sector-1], selectedSCSectorOffset->GetBinContent(sector), meanSCOffset, sc_tdc_time_offsets[sector-1] + selectedSCSectorOffset->GetBinContent(sector) - meanSCOffset); } outFile.close(); if (verbose){ cout << "ADC Offsets" << endl; cout << "Sector\tvalueToUse\toldValue\tmeanOffset\tTotal" << endl; } 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; if (verbose) printf("%i\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\n",sector,sc_fadc_time_offsets[sector-1], selectedSCSectorOffset->GetBinContent(sector), meanSCOffset, sc_fadc_time_offsets[sector-1] + selectedSCSectorOffset->GetBinContent(sector) - meanSCOffset); } outFile.close(); outFile.open(prefix + "sc_base_time.txt"); outFile << sc_t_base_fadc - meanSCOffset << " " << sc_t_base_tdc - meanSCOffset << endl; if (verbose) { printf("SC ADC Base = %f - (%f) = %f\n", sc_t_base_fadc, meanSCOffset, sc_t_base_fadc - meanSCOffset); printf("SC TDC Base = %f - (%f) = %f\n", sc_t_base_tdc, meanSCOffset, sc_t_base_tdc - meanSCOffset); } outFile.close(); } TH1I *this1DHist = ExtractTrackBasedTimingNS::Get1DHistogram("HLDetectorTiming", "TRACKING", "TOF - RF 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"); if (verbose) { printf("TOF ADC Base = %f - (%f) - (%f) = %f\n", tof_t_base_fadc, mean, meanSCOffset, tof_t_base_fadc - mean - meanSCOffset); printf("TOF TDC Base = %f - (%f) - (%f) = %f\n", tof_t_base_tdc, mean, meanSCOffset, tof_t_base_tdc - mean - meanSCOffset); } outFile << tof_t_base_fadc - mean - meanSCOffset<< " " << tof_t_base_tdc - mean - meanSCOffset<< endl; outFile.close(); } this1DHist = ExtractTrackBasedTimingNS::Get1DHistogram("HLDetectorTiming", "TRACKING", "BCAL - RF 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"); if (verbose) { printf("BCAL ADC Base = %f - (%f) - (%f) = %f\n", bcal_t_base_fadc, mean, meanSCOffset, bcal_t_base_fadc - mean - meanSCOffset); printf("BCAL TDC Base = %f - (%f) - (%f) = %f\n", bcal_t_base_tdc, mean, meanSCOffset, bcal_t_base_tdc - mean - meanSCOffset); } outFile << bcal_t_base_fadc - mean - meanSCOffset << " " << bcal_t_base_tdc - mean - meanSCOffset << endl; // TDC info not used outFile.close(); } this1DHist = ExtractTrackBasedTimingNS::Get1DHistogram("HLDetectorTiming", "TRACKING", "FCAL - RF 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"); if (verbose) { printf("FCAL ADC Base = %f - (%f) - (%f) = %f\n",fcal_t_base, mean, meanSCOffset, fcal_t_base - mean - meanSCOffset); } outFile << fcal_t_base - mean - meanSCOffset<< endl; outFile.close(); } this1DHist = ExtractTrackBasedTimingNS::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"); if (verbose) { printf("CDC ADC Base = %f - (%f) - (%f) = %f\n",cdc_t_base, mean, meanSCOffset, cdc_t_base - mean - meanSCOffset); } outFile << cdc_t_base - mean - meanSCOffset << endl; outFile.close(); } // We want to account for any residual difference between the cathode and anode times. double FDC_ADC_Offset = 0.0, FDC_TDC_Offset = 0.0; this1DHist = ExtractTrackBasedTimingNS::Get1DHistogram("HLDetectorTiming", "FDC", "FDCHit Cathode time;1"); if(this1DHist != NULL){ Int_t firstBin = this1DHist->FindFirstBinAbove( 1 , 1); // Find first bin with content above 1 in the histogram for (int i = 0; i <= 16; i++){ if ((firstBin + i) > 0) this1DHist->SetBinContent((firstBin + i), 0); } //Fit a gaussian to the left of the main peak Double_t maximum = this1DHist->GetBinCenter(this1DHist->GetMaximumBin()); TF1 *f = new TF1("f", "gaus"); f->SetParameters(100, maximum, 20); //this1DHist->Rebin(2); TFitResultPtr fr = this1DHist->Fit(f, "S", "", maximum - 10, maximum + 7); // Cant fix value at end of range double mean = fr->Parameter(1); float sigma = fr->Parameter(2); FDC_ADC_Offset = mean; delete f; } this1DHist = ExtractTrackBasedTimingNS::Get1DHistogram("HLDetectorTiming", "FDC", "FDCHit Wire time;1"); if(this1DHist != NULL){ Int_t firstBin = this1DHist->FindLastBinAbove( 1 , 1); // Find first bin with content above 1 in the histogram for (int i = 0; i <= 25; i++){ if ((firstBin + i) > 0) this1DHist->SetBinContent((firstBin + i), 0); } //Fit a gaussian to the left of the main peak Double_t maximum = this1DHist->GetBinCenter(this1DHist->GetMaximumBin()); TF1 *f = new TF1("f", "gaus"); f->SetParameters(100, maximum, 20); TFitResultPtr fr = this1DHist->Fit(f, "S", "", maximum - 10, maximum + 5); // Cant fix value at end of range double mean = fr->Parameter(1); float sigma = fr->Parameter(2); FDC_TDC_Offset = mean; delete f; } double FDC_ADC_TDC_Offset = FDC_ADC_Offset - FDC_TDC_Offset; this1DHist = ExtractTrackBasedTimingNS::Get1DHistogram("HLDetectorTiming", "TRACKING", "Earliest Flight-time Corrected FDC Time"); if(this1DHist != NULL){ //Landau Double_t maximum = this1DHist->GetBinCenter(this1DHist->GetMaximumBin()); TFitResultPtr fr = this1DHist->Fit("landau", "S", "", maximum - 2.5, maximum + 4); float MPV = fr->Parameter(1); outFile.open(prefix + "fdc_base_time.txt"); if (verbose) { printf("FDC ADC Base = %f - (%f) - (%f) - (%f) = %f\n",fdc_t_base_fadc, MPV, meanSCOffset, FDC_ADC_TDC_Offset, fdc_t_base_fadc - MPV - meanSCOffset - FDC_ADC_TDC_Offset); printf("FDC TDC Base = %f - (%f) - (%f) = %f\n",fdc_t_base_tdc, MPV, meanSCOffset, fdc_t_base_tdc - MPV - meanSCOffset); } outFile << fdc_t_base_fadc - MPV - meanSCOffset - FDC_ADC_TDC_Offset << " " << fdc_t_base_tdc - MPV - meanSCOffset << endl; outFile.close(); } ExtractTrackBasedTimingNS::thisFile->Write(); return; }
int frameStack2_Mall(char* arg){ //Take the arguments and save them into respective strings std::string infileName, outfileName0, outAllfileName0, outfileName1, outAllfileName1; std::string inF, outF0, outF1, outAll0, outAll1; std::string inPrefix, outPrefix; std::string runs, layers; std::string runCount; std::istringstream stm(arg); inPrefix = "/home/p180f/Do_Jo_Ol_Ma/Analysis/MainProcedure/testMain/rawRoot/"; outPrefix = "/home/p180f/Do_Jo_Ol_Ma/Analysis/MainProcedure/testMain/images/"; outAll0 = "sliceXCuts_allLayers.png"; outAllfileName0 = outPrefix + outAll0; std::cout << outAll0 << " created\n"; outAll1 = "projYCuts_allLayers.png"; outAllfileName1 = outPrefix + outAll1; std::cout << outAll1 << " created\n"; const int width=480; //width of the raw image const int height=640; //height of the raw image TH2I *frameHistoAll = new TH2I("frameHistoAll","Stacked Frames After Edge Cuts",width/4,0,width,height/4,0,height); //histogram for the stacked images TH1I *chamber1All = new TH1I("chamber1All","Chamber 1 After Edge Cuts",width/4,0,width);//histogram for chamber 1 (the top one) TH1I *chamber2All = new TH1I("chamber2All","Chamber 2 After Edge Cuts",width/4,0,width);//histogram for chamber 2 TH1I *chamber3All = new TH1I("chamber3All","Chamber 3 After Edge Cuts",width/4,0,width);//histogram for chamber 3 TH1I *chamber4All = new TH1I("chamber4All","Chamber 4 After Edge Cuts",width/4,0,width);//histogram for chamber 4 (the bottom one) TCanvas *projCAll = new TCanvas("projCAll","",0,0,800,600); TCanvas *pc2All = new TCanvas("pc2All", "Stack of 4 Layer Runs", 0, 0, 800, 600); while (true) { if (std::getline(stm, layers, ' ')) { //create the output root file outF0 = "sliceXCuts_" + layers + "layers.png"; outfileName0 = outPrefix + outF0; std::cout << outF0 << " created\n"; outF1 = "projYCuts_" + layers + "layers.png"; outfileName1 = outPrefix + outF1; std::cout << outF1 << " created\n"; //load the input root files TChain *chain = new TChain("fourChamTree"); for (int i=0; ; i++) { runCount = std::to_string(i); inF = "run" + runCount + "_" + layers + "layers.root"; infileName = inPrefix + inF; ifstream fin; fin.open(infileName.c_str()); if (!fin.fail()) { fin.close(); chain->Add(infileName.c_str()); std::cout << "Got " << inF << std::endl; } else break; } int x=-10; //x from file int y=-10; //y from file int intensity=-10; //pixle intensity from file int pNum=0;//the order in which the frame was processed //the 2d array which will store each frame of image data. int frame[480][640]={0}; //variables int UNIXtime=0; float tdc[2]={-10,-10}; //TTree *T = new TTree("T","TTree of muplus data"); //add the 'branches' to the tree we will now read in chain->SetBranchAddress("pNum",&pNum); //branch for the frame number chain->SetBranchAddress("frame",&frame); //branch for frame data TH2I *frameHisto = new TH2I("frameHisto","Stacked Frames After Edge Cuts",width/4,0,width,height/4,0,height); //histogram for the stacked images TH1I *chamber1 = new TH1I("chamber1","Chamber 1 After Edge Cuts",width/4,0,width);//histogram for chamber 1 (the top one) TH1I *chamber2 = new TH1I("chamber2","Chamber 2 After Edge Cuts",width/4,0,width);//histogram for chamber 2 TH1I *chamber3 = new TH1I("chamber3","Chamber 3 After Edge Cuts",width/4,0,width);//histogram for chamber 3 TH1I *chamber4 = new TH1I("chamber4","Chamber 4 After Edge Cuts",width/4,0,width);//histogram for chamber 4 (the bottom one) //loop over all data in chain Int_t nevent = chain->GetEntries(); //get the number of entries in the TChain for (Int_t i=0;i<nevent;i++) { chain->GetEntry(i); for(int x=0;x<width;x++){ for(int y=0;y<height;y++){ if(frame[x][y]>0){ frameHisto->Fill(x,y,frame[x][y]); frameHistoAll->Fill(x,y,frame[x][y]); if(y>580 && y<610){ chamber1->Fill(x,frame[x][y]); chamber1All->Fill(x,frame[x][y]); } else if(y>400 && y<440){ chamber2->Fill(x,frame[x][y]); chamber2All->Fill(x,frame[x][y]); } else if(y>240 && y<280){ chamber3->Fill(x,frame[x][y]); chamber3All->Fill(x,frame[x][y]); } else if(y>50 && y<100){ chamber4->Fill(x,frame[x][y]); chamber4All->Fill(x,frame[x][y]); } } } } cout << "Stacking frame number " << pNum << "\r";//this overwrites the line every time } cout << endl; //output the plot of the stacked images TCanvas *pc2 = new TCanvas("pc2","Stacked Frames",0,0,600,800); pc2->cd(); frameHisto->SetStats(false); frameHisto->Draw("colz"); frameHisto->GetXaxis()->SetTitle("X position (px)"); //frameHisto->GetXaxis()->SetTitleSize(0.055); //frameHisto->GetXaxis()->SetTitleOffset(1.0); //frameHisto->GetXaxis()->SetLabelSize(0.055); frameHisto->GetXaxis()->CenterTitle(); frameHisto->GetYaxis()->SetTitle("Y position (px)"); //frameHisto->GetYaxis()->SetTitleSize(0.055); //frameHisto->GetYaxis()->SetTitleOffset(0.9); //frameHisto->GetYaxis()->SetLabelSize(0.055); frameHisto->GetYaxis()->CenterTitle(); gPad->Update(); // pc2->Print("chamberStack.png");//output to a graphics file //plot the projection onto the Y axis (so we can find our cuts in Y to select each chamber) TCanvas *projC = new TCanvas("projC","",0,0,800,600); projC->cd(); TH1D *ydist = frameHisto->ProjectionY("ydist"); ydist->Draw(); ydist->GetYaxis()->SetTitle("Entries"); ydist->GetYaxis()->CenterTitle(); TCanvas *sliceX = new TCanvas("sliceX","",0,0,800,600); sliceX->Divide(2,2); sliceX->cd(1); chamber1->Draw(); chamber1->GetXaxis()->SetTitle("X position (px)"); chamber1->GetXaxis()->CenterTitle(); chamber1->GetYaxis()->SetTitle("Y position (px)"); chamber1->GetYaxis()->CenterTitle(); // chamber1->GetYaxis()->SetMaxDigits(2); sliceX->cd(2); chamber2->Draw(); chamber2->GetXaxis()->SetTitle("X position (px)"); chamber2->GetXaxis()->CenterTitle(); chamber2->GetYaxis()->SetTitle("Y position (px)"); chamber2->GetYaxis()->CenterTitle(); // chamber2->GetYaxis()->SetMaxDigits(2); sliceX->cd(3); chamber3->Draw(); chamber3->GetXaxis()->SetTitle("X position (px)"); chamber3->GetXaxis()->CenterTitle(); chamber3->GetYaxis()->SetTitle("Y position (px)"); chamber3->GetYaxis()->CenterTitle(); // chamber3->GetYaxis()->SetMaxDigits(2); sliceX->cd(4); chamber4->Draw(); chamber4->GetXaxis()->SetTitle("X position (px)"); chamber4->GetXaxis()->CenterTitle(); chamber4->GetYaxis()->SetTitle("Y position (px)"); chamber4->GetYaxis()->CenterTitle(); // chamber4->GetYaxis()->SetMaxDigits(2); gPad->Update(); projC->Print(outfileName1.c_str()); sliceX->Print(outfileName0.c_str()); frameHisto->Reset(); chamber1->Reset(); chamber2->Reset(); chamber3->Reset(); chamber4->Reset(); } else break; } projCAll->cd(); TH1D *ydistAll = frameHistoAll->ProjectionY("ydist"); ydistAll->Draw(); ydistAll->GetYaxis()->SetTitle("Entries"); ydistAll->GetYaxis()->CenterTitle(); TCanvas *sliceXAll = new TCanvas("sliceXAll","",0,0,800,600); sliceXAll->Divide(2,2); sliceXAll->cd(1); chamber1All->Draw(); chamber1All->GetXaxis()->SetTitle("X position (px)"); chamber1All->GetXaxis()->CenterTitle(); chamber1All->GetYaxis()->SetTitle("Y position (px)"); chamber1All->GetYaxis()->CenterTitle(); // chamber1->GetYaxis()->SetMaxDigits(2); sliceXAll->cd(2); chamber2All->Draw(); chamber2All->GetXaxis()->SetTitle("X position (px)"); chamber2All->GetXaxis()->CenterTitle(); chamber2All->GetYaxis()->SetTitle("Y position (px)"); chamber2All->GetYaxis()->CenterTitle(); // chamber2->GetYaxis()->SetMaxDigits(2); sliceXAll->cd(3); chamber3All->Draw(); chamber3All->GetXaxis()->SetTitle("X position (px)"); chamber3All->GetXaxis()->CenterTitle(); chamber3All->GetYaxis()->SetTitle("Y position (px)"); chamber3All->GetYaxis()->CenterTitle(); // chamber3->GetYaxis()->SetMaxDigits(2); sliceXAll->cd(4); chamber4All->Draw(); chamber4All->GetXaxis()->SetTitle("X position (px)"); chamber4All->GetXaxis()->CenterTitle(); chamber4All->GetYaxis()->SetTitle("Y position (px)"); chamber4All->GetYaxis()->CenterTitle(); // chamber4->GetYaxis()->SetMaxDigits(2); gPad->Update(); projCAll->Print(outAllfileName1.c_str()); sliceXAll->Print(outAllfileName0.c_str()); pc2All->cd(); frameHistoAll->SetStats(false); frameHistoAll->Draw("colz"); frameHistoAll->GetXaxis()->SetTitle("X position (px)"); //frameHisto->GetXaxis()->SetTitleSize(0.055); //frameHisto->GetXaxis()->SetTitleOffset(1.0); //frameHisto->GetXaxis()->SetLabelSize(0.055); frameHistoAll->GetXaxis()->CenterTitle(); frameHistoAll->GetYaxis()->SetTitle("Y position (px)"); //frameHisto->GetYaxis()->SetTitleSize(0.055); //frameHisto->GetYaxis()->SetTitleOffset(0.9); //frameHisto->GetYaxis()->SetLabelSize(0.055); frameHistoAll->GetYaxis()->CenterTitle(); gPad->Update(); return 0; }
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; }