void os2d(complexFloat *v, complexFloat *vo, int dim, int os) { int i; int forward_fft = 1; int inverse_fft = -1; int osize; /* printf("os2d(): dim = %d\tos = %d\n", dim, os); */ /* calculate total size of oversampled array */ osize = dim*dim*os*os; /* printf("os2d(): total size of oversampled array (osize) = %d\n", osize); */ /* 2-D fft vector 'v' */ fft2d (v, dim, forward_fft); /* make sure 'vo' = 0.0 */ for (i = 0; i < osize; i++) *(vo+i) = Czero(); /* zero pad 'v' into 'vout' */ zeroPad(v, vo, dim, os); /* inverse FFT 'vo' */ fft2d (vo, dim*os, inverse_fft); return; }
QString MetaBundle::prettyTime( uint seconds, bool showHours ) //static { QString s = QChar( ':' ); s.append( zeroPad( seconds % 60 ) ); //seconds seconds /= 60; if( showHours && seconds >= 60) { s.prepend( zeroPad( seconds % 60 ) ); //minutes s.prepend( ':' ); seconds /= 60; } //don't zeroPad the last one, as it can be greater than 2 digits s.prepend( QString::number( seconds ) ); //hours or minutes depending on above if block return s; }
inline void findPeak(double *idata, place * odata, int siz, int pitch) { place p = {0u, 0.0}; zeroPad(idata, siz, pitch); unsigned int n = siz * pitch; #pragma omp declare reduction (maxer: place : omp_out = pmax(omp_out, omp_in)) #pragma omp parallel for reduction(maxer: p) for (unsigned int i = 0; i<n; i++) { p = pmax(p, {n, fabs(idata[n])}); } *odata = p; }
int main(int argc, char* argv[]) { // Single byte to be read from the data files char c; // Counters to keep track of cuts unsigned long waveformCtr = 0; unsigned long linearGateCtr = 0; unsigned long muonVetoCtr = 0; unsigned long overflowCtr = 0; unsigned long bgAnalysisCtr = 0; unsigned long sAnalysisCtr = 0; // Variables for the background output files int bg_counter = 0; int bg_file_number = 0; std::ofstream bg_out_file; // Variables for the signal output files int s_counter = 0; int s_file_number = 0; std::ofstream s_out_file; // Run Info output std::ofstream infoOut; // Saved waveforms std::ofstream waveformOut; // LabView headers int no_samples = 0; int no_channels = 0; // Timestamp of current trigger std::string timestamp; // Waveform buffers int csi [35000] = {} ; int csi_raw[35000] = {} ; int mv [35000] = {} ; // Buffer to store bit shifted samples int _tmpC = 0; // Medians of CsI and muon veto int med_csi = 0; int med_mv = 0; // Buffers used for median calculation as well as overflow detection unsigned int med_csi_sum = 0; unsigned int med_mv_sum = 0; unsigned int med_csi_arr [256] = {} ; unsigned int med_mv_arr [256] = {}; bool med_csi_found = false; bool med_mv_found = false; bool overflow = false; // Buffers for SPE integration int spe_charge_dist[300] = {}; int spe_integration_ctr = 0; int spe_integration_charge = 0; // Buffers for peaks in pretrace int bg_pe_pt[52] = {}; int s_pe_pt[52] = {}; // Buffer for baseline int baseline_hist[32] = {}; // Rising and falling threshold crossings used for linear gate detection int _previous_c = 0; int gate_down = 0; int gate_up = 0; // Waveform contains a gate or muon veto fired more than three times bool linear_gate = false; bool muon_veto_flag = false; // Photoelectron counter for all interesting regions // pt = pretrace, roi = region of interest, iw = integration window unsigned int s_pt_ct = 0; unsigned int bg_pt_ct = 0; unsigned int s_roi_ct = 0; unsigned int bg_roi_ct = 0; unsigned int s_iw_ct = 0; unsigned int bg_iw_ct = 0; unsigned int PE_max_PT = 10; // Buffers to store current peak width in CsI and muon veto waveform int above_pe_threshold = 0; int current_peak_width = 0; int current_pe_width = 0; int m_peak_width = 0; // Peak thresholds int peak_height_threshold = 3; int peak_width_threshold = 4; // Peak locations in CsI, Muon locations in muon veto std::vector<int> peaks; std::vector<int> peak_heights; int peak_height_dist[100] = {}; int peak_amplitude = 0; std::vector<int> pe_beginnings; std::vector<int> pe_endings; std::vector<int> muon_peaks; std::vector<int> muon_onset_arr; // Keep track of all peak/pe locations in the full minute int peak_distribution[350][350] = {}; int charge_distribution[350][350] = {}; for (int i1 = 0; i1 < 350; i1++) { for (int i2 = 0; i2 < 350; i2++) { peak_distribution[i1][i2] = 0; charge_distribution[i1][i2] = 0; } } // Get peak width distribution int peak_width_distribution[51] = {}; // Charge of PE in PT int current_spe_q = 0; // Integration window buffers int s_q_arr [1500] = {}; int bg_q_arr [1500] = {}; int running_charge = 0; // LogLikelihood prefactors & estimators double lnL_pf_real[1500] = {}; double lnL_pf_flat[1500] = {}; double lnL_real = 0; double lnL_flat = 0; // Big pulse detection bool bP_detected = false; int _t_bP_idx = 0; std::vector<int> bP_onset_arr; std::vector<int> bP_charge_arr; // Calculate prefactors for loglikelihood analysis // timing and fraction from NIMA paper double r = 0.41; double tf = 527.0; double ts = 5600.0; // total integration window is 3 us long -> tMax = 1500 double _tFast = 1.0 / ((1.0 + r) * tf * (1 - exp(-1500.0 / tf))); double _tSlow = r / ((1.0 + r) * ts * (1 - exp(-1500.0 / ts))); // Calculate prefactor for each time step for (int i = 0; i < 1500; i++) { lnL_pf_real[i] = log(_tFast * exp(-(double)i / tf) + _tSlow * exp(-(double)i / ts)); lnL_pf_flat[i] = log(1.0 / 1500.0); } // Threshold buffer and measured rise times double thresholds [3] = {}; double bg_rt [3] = {}; double s_rt [3] = {}; // Buffers used during window analysis int idx_0 = 0; int idx_w_offset = 0; int i_peak = 0; int i_pe = 0; int q_int = 0; double _t1 = 0.0; double _t2 = 0.0; std::string main_dir; int current_time; int single_time; std::string out_dir; std::string current_zip_file; std::string time_name_in_zip; // Save waveforms as ascii - Counter,cuts etc int save_wf_ctr = 0; int no_total_peaks[2] = { 100, 200 }; int minimum_no_peaks_iw = 6; int rt1090_bottom_left[2] = { 750, 1150 }; int rt050_bottom_left[2] = { 235, 345 }; int rt1090_upper_right[2] = { 1080, 1280 }; int rt050_upper_right[2] = { 520, 760 }; bool save_waveforms = false; bool passed_cuts_bg = false; bool passed_cuts_s = false; bool passed_cut = false; // Set main run directory, e.g. Run-15-10-02-27-32-23/151002 // Set current time to be analzyed as index of sorted number of total files in folder, e.g. 0-1439 for a full day // Set output directory, eg Output/ Run-15-10-02-27-32-23/151002 int data_set = 0; if (argc == 6) { data_set = atoi(argv[1]); main_dir = std::string(argv[2]); current_time = atoi(argv[3]); out_dir = std::string(argv[4]); single_time = atoi(argv[5]); } else { std::cout << "Arguments not matching! Aborting now!" << std::endl; return 1; } unsigned int BG_PT[2] = {}; unsigned int BG_ROI[2] = {}; unsigned int S_PT[2] = {}; unsigned int S_ROI[2] = {}; switch (data_set) { case 1: BG_PT[0] = 0; BG_PT[1] = 19975; BG_ROI[0] = 19975; BG_ROI[1] = 27475; S_PT[0] = 7500; S_PT[1] = 27475; S_ROI[0] = 27475; S_ROI[1] = 34975; PE_max_PT = 10; break; case 2: BG_PT[0] = 0; BG_PT[1] = 20000; BG_ROI[0] = 20000; BG_ROI[1] = 27400; S_PT[0] = 7400; S_PT[1] = 27400; S_ROI[0] = 27400; S_ROI[1] = 35000; PE_max_PT = 20; break; case 3: BG_PT[0] = 0; BG_PT[1] = 17500; BG_ROI[0] = 17500; BG_ROI[1] = 25000; S_PT[0] = 7500; S_PT[1] = 25000; S_ROI[0] = 25000; S_ROI[1] = 32500; PE_max_PT = 30; break; default: std::cout << "Arguments not matching! Aborting now!" << std::endl; return 1; } // Full analysis -> Converts $(Process) from condor submit to the current time file if (single_time == 0) { // Buffers used to process data files and to step through directories std::vector<std::string> time_files; DIR *dpdf; struct dirent *epdf; // Find all time files and sort them time_files.clear(); dpdf = opendir(main_dir.c_str()); if (dpdf != NULL) { std::string _tmp; while (epdf = readdir(dpdf)) { _tmp = epdf->d_name; if (_tmp != "." && _tmp != ".." && _tmp.substr(7) == "zip") { time_files.push_back(_tmp.substr(0, 6)); } } } // Sort time files by time in ascending order to convert current_time index to proper file std::sort(time_files.begin(), time_files.end(), timeSort); // Prepare paths to zipped and unzipped files current_zip_file = main_dir + "/" + time_files[current_time] + ".zip"; time_name_in_zip = time_files[current_time]; } // Single file analysis -> Directly convert input to current time file else { current_zip_file = main_dir + "/" + zeroPad(current_time,6) +".zip"; time_name_in_zip = zeroPad(current_time,6); } //Open the ZIP archive int err = 0; int zidx = 0; int fileSize = 0; zip *z = zip_open(current_zip_file.c_str(), 0, &err); //Search for the file of given name const char *name = time_name_in_zip.c_str(); struct zip_stat st; zip_stat_init(&st); zip_stat(z, name, 0, &st); //Alloc memory for its uncompressed contents char *contents = new char[st.size]; // Unzip the compressed file into memory zip_file *f = zip_fopen(z, time_name_in_zip.c_str(), 0); fileSize = st.size; zip_fread(f, contents, fileSize); zip_fclose(f); //And close the archive zip_close(z); // Create signal, background and info output files bg_out_file.open((out_dir + "/" + fileName(atoi(time_name_in_zip.c_str()), "B-")).c_str(), std::ofstream::out | std::ofstream::trunc); s_out_file.open((out_dir + "/" + fileName(atoi(time_name_in_zip.c_str()), "S-")).c_str(), std::ofstream::out | std::ofstream::trunc); infoOut.open((out_dir + "/" + fileName(atoi(time_name_in_zip.c_str()), "I-")).c_str(), std::ofstream::out | std::ofstream::trunc); if (save_waveforms) { waveformOut.open((out_dir + "/" + fileName(atoi(time_name_in_zip.c_str()), "W-")).c_str(), std::ofstream::out | std::ofstream::trunc); } // Begin data processing if file has been properly opened if(err == 0) { waveformCtr = 0; zidx = 0; // Begin reading byte-stream while (zidx < fileSize) { // Read LabView header and get the total number of samples written for each channel in the next chunk of data for (int i=0;i<4;i++) { c = contents[zidx++]; no_samples = no_samples << 8 | (unsigned char) c; } // Read LabView header and get the total number of channels written in next chunk of data (always 2 in our case) for (int i=0;i<4;i++) { c = contents[zidx++]; no_channels = no_channels << 8 | (unsigned char) c; } // Takes care of LabViews closing bit... if (no_samples > 350070) { break; } // ---------------------------------------------------------------- // Process XYZ consecutive waveforms without encountering another // LabView header inbetween // ---------------------------------------------------------------- for (int wf=0; wf < (int) (no_samples/35007); wf++) { // A new waveform begins waveformCtr += 1; // ------------------------------------------------------------- // Reset all major waveform specific variables // ------------------------------------------------------------- timestamp.clear(); overflow = false; linear_gate = false; muon_veto_flag = false; _previous_c = 128; gate_down = 0; gate_up = 0; memset(med_csi_arr,0,sizeof med_csi_arr); memset(med_mv_arr,0,sizeof med_mv_arr ); med_csi_found = false; med_mv_found = false; med_csi_sum = 0; med_mv_sum = 0; above_pe_threshold = 0; current_peak_width = 0; current_pe_width = 0; current_spe_q = 0; m_peak_width = 0; peaks.clear(); peak_heights.clear(); pe_beginnings.clear(); pe_endings.clear(); muon_peaks.clear(); spe_integration_ctr = 0; spe_integration_charge = 0; passed_cuts_s = false; passed_cuts_bg = false; passed_cut = false; peak_amplitude = 0; bP_detected = false; _t_bP_idx = 0; // ------------------------------------------------------------- // Read current timestamp // ------------------------------------------------------------- for(int i=0; i<7; i++) { c = contents[zidx++]; c = contents[zidx++]; timestamp += zeroPad((int) c, 2); } // --------------------------------------------------------------- // Read the full CsI and muon veto waveforms from the zip-stream // + Apply bit transformation // + Determine if a linear gate is present // --------------------------------------------------------------- for(int i=0; i<35000; i++) { //-------------- // CsI //-------------- c = contents[zidx++]; // bit transformation to get rid of empty bins _tmpC = (int) c - (int) floor(((double) c + 5.0)/11.0); if (i<20000){ med_csi_arr[_tmpC + 128] += 1; } csi[i] = _tmpC; csi_raw[i] = _tmpC; if (i == 0) { _previous_c = _tmpC; } // Gate check if (_tmpC <= 18 && _previous_c > 18) { gate_down++; } if (_previous_c <= 18 && _tmpC > 18) { gate_up++; } _previous_c = _tmpC; // Overflow check if (!overflow && (c >= 127 || c == -128)) { overflow = true; overflowCtr += 1; } //-------------- // Muon Veto //-------------- c = contents[zidx++]; _tmpC = (int) c + (int) ((signbit((int) c) ? -1 : 1 ) * floor((4.0 - abs((double) c))/11.0)); med_mv_arr[_tmpC + 128] += 1; mv[i] = _tmpC; } // --------------------------------------- // Calculate the median of both channels // --------------------------------------- for(int i=0; i<256; i++) { if (!med_csi_found) { med_csi_sum += med_csi_arr[i]; if (med_csi_sum >= 10000) { med_csi = i-128; med_csi_found=true; } } if (!med_mv_found) { med_mv_sum += med_mv_arr[i]; if (med_mv_sum >= 10000) { med_mv = i-128; med_mv_found=true; } } } // ---------------------------------------------- // Adjust linear gate counter if wf is gated // ---------------------------------------------- if (gate_down != gate_up || med_csi < 50) { linear_gate = true; linearGateCtr += 1; } // ----------------------------------------------- // Find peaks and photoelectrons in waveforms // ----------------------------------------------- current_peak_width = 0; peak_amplitude = 0; bP_detected = false; for (int i = 0; i < 35000; i++) { // ------------------------------------------- // Analyze CsI[Na] waveform // ------------------------------------------- csi[i] = med_csi - csi[i]; // Simple peak finder using threshold crossing with history if (csi[i] >= peak_height_threshold) { current_peak_width++; peak_amplitude = csi[i] > peak_amplitude ? csi[i] : peak_amplitude; } else { if (current_peak_width >= peak_width_threshold) { peaks.push_back(i - current_peak_width); pe_beginnings.push_back((i - current_peak_width - 2) >= 0 ? (i - current_peak_width - 2) : 0); pe_endings.push_back((i + 1) <= 34999 ? (i + 1) : 34999); peak_width_distribution[(current_peak_width < 50) ? current_peak_width : 50] += 1; peak_heights.push_back(peak_amplitude); // Check for large energy depositions if (!bP_detected && current_peak_width >= 35 && !linear_gate && !overflow) { bP_detected = true; bP_onset_arr.push_back(i - current_peak_width); } } current_peak_width = 0; peak_amplitude = 0; } // ------------------------------------------- // Analyze muon veto waveform // ------------------------------------------- mv[i] = med_mv - mv[i]; // Peak finder if (mv[i] >= 10) { m_peak_width++; } else { if (m_peak_width >= 3) { muon_peaks.push_back(i-m_peak_width); } m_peak_width = 0; } } // If there was a big pulse in the trace integrate it // But only if there was no linear gate or overflow if (bP_detected && !linear_gate && !overflow) { int _t_charge = 0; for (int i = bP_onset_arr.back(); i < (1500 + bP_onset_arr.back()); i++) { _t_charge += (csi[i] >= peak_height_threshold) ? csi[i] : 0; } bP_charge_arr.push_back(_t_charge); } // Raise muon veto flag if more than three muons have been found // If less than 3 have been found fill the vector with -1 for postprocessing int muons_found = muon_peaks.size(); if (muons_found > 0) { if (linear_gate) { muon_onset_arr.push_back(muon_peaks[0]); } else { for (std::vector<int>::size_type idx = 0; idx < muons_found; idx++) { muon_onset_arr.push_back(muon_peaks[idx]); } } } if (muons_found > 3) { muon_veto_flag = true; muonVetoCtr += 1; } else { muon_peaks.resize(3, -1); } // Add PE peaks to peak height distribution if (peak_heights.size() > 0 && !overflow && !linear_gate) { for (int idx = 0; idx < peak_heights.size(); idx++) { peak_height_dist[(peak_heights[idx] < 100) ? peak_heights[idx] : 99]++; } } // ======================================================================== // Check that there is at least one PE in the trace, there is no overflow, // no linear gate and no muon veto flag, otherwise continue to next // waveform without bothering to analyze this one // ======================================================================== bool analyze = false; if (data_set == 1 && !overflow && !linear_gate && !muon_veto_flag) { analyze = true; } if (data_set == 2 && !overflow && !linear_gate) { analyze = true; } if (data_set == 3 && !overflow && !linear_gate) { analyze = true; } if (analyze && pe_beginnings.size() > 0) { // ------------------------------------------------------------- // Integrate all SPE found in the PT and histogram their charge // ------------------------------------------------------------- for (std::vector<int>::size_type idx = 0; idx < pe_beginnings.size(); idx++) { if (pe_beginnings[idx] < BG_PT[1]) { current_spe_q = 0; for (int i = pe_beginnings[idx]; i <= pe_endings[idx]; i++) { current_spe_q += csi[i]; } if (current_spe_q >= -50 && current_spe_q < 250) { spe_charge_dist[(current_spe_q+50)] += 1; } } else { break; } } // ------------------------------------------------------------- // Determine number of PE in different regions // ------------------------------------------------------------- bg_pt_ct = 0; bg_roi_ct = 0; bg_iw_ct = 0; s_pt_ct = 0; s_roi_ct = 0; s_iw_ct = 0; if (peaks.size() > 0) { for (std::vector<int>::size_type idx = 0; idx < peaks.size(); idx++) { if (peaks[idx] >= BG_PT[0] && peaks[idx] < BG_PT[1]) { bg_pt_ct += 1; } if (peaks[idx] >= S_PT[0] && peaks[idx] < S_PT[1]) { s_pt_ct += 1; } if (peaks[idx] >= BG_ROI[0] && peaks[idx] < BG_ROI[1]) { bg_roi_ct += 1; } if (peaks[idx] >= S_ROI[0] && peaks[idx] < S_ROI[1]) { s_roi_ct += 1; } } // Distribution of charge (only add >= 3) if (true) { int sz = peaks.size() / 2; if (sz < 350) { int cpi = 0; for (int idx = 0; idx < 35000; idx++) { // Add sample if it is within one of the PE regions identified previously if (idx >= pe_beginnings[cpi] && idx <= pe_endings[cpi]) { charge_distribution[sz][idx / 100] += csi[idx]; if (idx >= pe_endings[cpi]) { if (++cpi >= pe_beginnings.size()){ break; } } } } } } } // Histogram baseline and peaks in pretrace if (!overflow && !linear_gate && !muon_veto_flag) { int _t_med_csi_bin = med_csi - 85; if (_t_med_csi_bin >= 0 && _t_med_csi_bin <=30) { baseline_hist[_t_med_csi_bin]++; } else { baseline_hist[31]++; } if (bg_pt_ct <= 50) { bg_pe_pt[bg_pt_ct]++; } else { bg_pe_pt[51]++; } if (s_pt_ct <= 50) { s_pe_pt[s_pt_ct]++; } else { s_pe_pt[51]++; } } // ------------------------------------------------------------- // Only analzye BG region if there are a maximum of PE_max_PT // & at least one PE in ROI // ------------------------------------------------------------- if (bg_pt_ct <= PE_max_PT && bg_roi_ct > 0) { bgAnalysisCtr += 1; // Reset window parameters idx_0 = 0; i_peak = 0; i_pe = 0; q_int = 0; lnL_real = 0.0; lnL_flat = 0.0; _t1 = 0.0; _t2 = 0.0; // ------------------------------------------------------------- // Determine onset of integration window by finding the first // PE in the region of interest // ------------------------------------------------------------- for (int i = 0; i < peaks.size(); i++) { if (peaks[i] >= BG_ROI[0]) { idx_0 = peaks[i]; i_peak = i; break; } } idx_0 -= 3; // ------------------------------------------------------------- // Only analyze if the full integration window is within the ROI // ------------------------------------------------------------- if (idx_0 < (BG_ROI[1] - 1500)) { // -------------------------------------------------------------- // Determine number of peaks in integration window (magic bullet) // -------------------------------------------------------------- for (int i = i_peak; i < peaks.size(); i++) { bg_iw_ct += (peaks[i] - idx_0 < 1500) ? 1 : 0; } // ------------------------------------------------------------- // Integrate over all PE found in the integration window // ------------------------------------------------------------- i_pe = i_peak; for (int i = 0; i < 1500; i++) { // Get proper 'real' index that includes the onset offset idx_w_offset = i + idx_0; // Add sample if it is within one of the PE regions identified previously as well as update loglikelihood estimators if (i_pe < pe_beginnings.size() && idx_w_offset >= pe_beginnings[i_pe] && idx_w_offset <= pe_endings[i_pe]) { q_int += csi[idx_w_offset]; lnL_real += lnL_pf_real[i] * csi[idx_w_offset]; lnL_flat += lnL_pf_flat[i] * csi[idx_w_offset]; if (idx_w_offset == pe_endings[i_pe]) { i_pe++; } } // Keep track of charge integration to determine rise times later bg_q_arr[i] = q_int; } // ------------------------------------------------------------- // Determine rise times // ------------------------------------------------------------- // Calculate charge thresholds thresholds[0] = 0.1*bg_q_arr[1499]; thresholds[1] = 0.5*bg_q_arr[1499]; thresholds[2] = 0.9*bg_q_arr[1499]; // Determine threshold crossing times for (int i = 0; i < 1499; i++) { _t1 = (double)bg_q_arr[i]; _t2 = (double)bg_q_arr[i + 1]; for (int j = 0; j < 3; j++) { if (_t1 < thresholds[j] && _t2 >= thresholds[j]){ bg_rt[j] = i + (thresholds[j] - _t1) / (_t2 - _t1); } } } // ------------------------------------------------------------- // If waveforms are being saved check whether cuts are passed // ------------------------------------------------------------- if (save_waveforms) { int rt1090 = (bg_rt[2] - bg_rt[0]); int rt050 = bg_rt[1]; bool bottom_left_cut = (rt1090 >= rt1090_bottom_left[0]) && (rt1090 <= rt1090_bottom_left[1]) && (rt050 >= rt050_bottom_left[0]) && (rt050 <= rt050_bottom_left[1]); bool upper_right_cut = (rt1090 >= rt1090_upper_right[0]) && (rt1090 <= rt1090_upper_right[1]) && (rt050 >= rt050_upper_right[0]) && (rt050 <= rt050_upper_right[1]); bool min_peak_cut = (bg_iw_ct >= minimum_no_peaks_iw); bool total_peak_cut = (peaks.size() >= no_total_peaks[0]) && (peaks.size() <= no_total_peaks[1]); passed_cuts_bg = (bottom_left_cut || upper_right_cut) && min_peak_cut && total_peak_cut; } // ------------------------------------------------------------- // Write analysis results to file // ------------------------------------------------------------- bg_out_file << timestamp << " " << med_csi << " " << med_mv << " "; bg_out_file << bg_pt_ct << " " << bg_roi_ct << " "; bg_out_file << bg_iw_ct << " " << idx_0 << " " << bg_q_arr[1499] << " " << lnL_real << " " << lnL_flat << " "; bg_out_file << bg_rt[0] << " " << bg_rt[1] << " " << bg_rt[2] << " "; bg_out_file << muon_peaks[0] << " " << muon_peaks[1] << " " << muon_peaks[2] << " " << peaks.size() << std::endl; // Keeps track of how many BG waveforms have actually been analyzed bg_counter++; } } // ------------------------------------------------------------- // Only analzye S region if there are a maximum of PE_max_PT // & at least one PE in ROI // ------------------------------------------------------------- if (s_pt_ct <= PE_max_PT && s_roi_ct > 0) { sAnalysisCtr += 1; // Reset window parameters idx_0 = 0; i_peak = 0; i_pe = 0; q_int = 0; lnL_real = 0.0; lnL_flat = 0.0; _t1 = 0.0; _t2 = 0.0; // ------------------------------------------------------------- // Determine onset of integration window by finding the first // PE in the region of interest // ------------------------------------------------------------- for (int i = 0; i < peaks.size(); i++) { if (peaks[i] >= S_ROI[0]) { idx_0 = peaks[i]; i_peak = i; break; } } idx_0 -= 3; // ------------------------------------------------------------- // Only analyze if the full integration window is within the ROI // ------------------------------------------------------------- if (idx_0 < (S_ROI[1] - 1500)) { // -------------------------------------------------------------- // Determine number of peaks in integration window (magic bullet) // -------------------------------------------------------------- for (int i = i_peak; i < peaks.size(); i++) { s_iw_ct += (peaks[i] - idx_0 < 1500) ? 1 : 0; } i_pe = i_peak; // ------------------------------------------------------------- // Integrate over all PE found in the integration window // ------------------------------------------------------------- for (int i = 0; i < 1500; i++) { // Get proper 'real' index that includes the onset offset idx_w_offset = i + idx_0; // Add sample if it is within one of the PE regions identified previously & update loglikelihood estimators if (i_pe < pe_beginnings.size() && idx_w_offset >= pe_beginnings[i_pe] && idx_w_offset <= pe_endings[i_pe]) { q_int += csi[idx_w_offset]; lnL_real += lnL_pf_real[i] * csi[idx_w_offset]; lnL_flat += lnL_pf_flat[i] * csi[idx_w_offset]; if (idx_w_offset == pe_endings[i_pe]) { i_pe++; } } // Keep track of charge integration to determine rise times later s_q_arr[i] = q_int; } // ------------------------------------------------------------- // Determine rise times // ------------------------------------------------------------- // Calculate charge thresholds thresholds[0] = 0.1*s_q_arr[1499]; thresholds[1] = 0.5*s_q_arr[1499]; thresholds[2] = 0.9*s_q_arr[1499]; // Determine threshold crossing times for (int i = 0; i < 1499; i++) { _t1 = (double)s_q_arr[i]; _t2 = (double)s_q_arr[i + 1]; for (int j = 0; j < 3; j++) { if (_t1 < thresholds[j] && _t2 >= thresholds[j]){ s_rt[j] = i + (thresholds[j] - _t1) / (_t2 - _t1); } } } // ------------------------------------------------------------- // If waveforms are being saved check whether cuts are passed // ------------------------------------------------------------- if (save_waveforms) { int rt1090 = (s_rt[2] - s_rt[0]); int rt050 = s_rt[1]; bool bottom_left_cut = (rt1090 >= rt1090_bottom_left[0]) && (rt1090 <= rt1090_bottom_left[1]) && (rt050 >= rt050_bottom_left[0]) && (rt050 <= rt050_bottom_left[1]); bool upper_right_cut = (rt1090 >= rt1090_upper_right[0]) && (rt1090 <= rt1090_upper_right[1]) && (rt050 >= rt050_upper_right[0]) && (rt050 <= rt050_upper_right[1]); bool min_peak_cut = (s_iw_ct >= minimum_no_peaks_iw); bool total_peak_cut = (peaks.size() >= no_total_peaks[0]) && (peaks.size() <= no_total_peaks[1]); passed_cuts_s = (bottom_left_cut || upper_right_cut) && min_peak_cut && total_peak_cut; } // ------------------------------------------------------------- // Write analysis results to file // ------------------------------------------------------------- s_out_file << timestamp << " " << med_csi << " " << med_mv << " "; s_out_file << s_pt_ct << " " << s_roi_ct << " "; s_out_file << s_iw_ct << " " << idx_0 << " " << s_q_arr[1499] << " " << lnL_real << " " << lnL_flat << " "; s_out_file << s_rt[0] << " " << s_rt[1] << " " << s_rt[2] << " "; s_out_file << muon_peaks[0] << " " << muon_peaks[1] << " " << muon_peaks[2] << " " << peaks.size() << std::endl; // Keeps track of how many BG waveforms have actually been analyzed s_counter++; } } } // ------------------------------------------------------------- // Save waveform if cuts have been passed for either ROI // ------------------------------------------------------------- if (save_waveforms && passed_cut) { for (int idx = 0; idx < 35000; idx++) { waveformOut << csi_raw[idx] << " "; } waveformOut << gate_up << " " << gate_down << " " << med_csi << " "; for (int idx = 0; idx < pe_beginnings.size(); idx++) { waveformOut << pe_beginnings[idx] << " " << pe_endings[idx] << " "; } waveformOut << std::endl; } } } } // Before exiting, make sure that both output files are properly closed to prevent data loss. if (bg_out_file.is_open()) { bg_out_file.close(); } if (s_out_file.is_open()) { s_out_file.close(); } // Write run info if (infoOut.is_open()) { infoOut << "Total number of Waveforms processed" << std::endl; infoOut << waveformCtr << std::endl; infoOut << "Number of triggers with linear gates in CsI channel" << std::endl; infoOut << linearGateCtr << std::endl; infoOut << "Number of triggers with overflows in either channel" << std::endl; infoOut << overflowCtr << std::endl; infoOut << "Number of triggers with more than 3 muons in muon veto channel" << std::endl; infoOut << muonVetoCtr << std::endl; infoOut << "Number of triggers that have actually been analyzed in the background window (less than x PE/peaks in PT + at least one PE/peak in ROI)" << std::endl; infoOut << bgAnalysisCtr << std::endl; infoOut << "Number of triggers that have actually been analyzed in the signal window (less than x PE/peaks in PT + at least one PE/peak in ROI)" << std::endl; infoOut << sAnalysisCtr << std::endl; infoOut << "Maximum number of PE/peaks in the pretrace" << std::endl; infoOut << PE_max_PT << std::endl; infoOut << "Background pretrace start" << std::endl; infoOut << BG_PT[0] << std::endl; infoOut << "Background pretrace stop" << std::endl; infoOut << BG_PT[1] << std::endl; infoOut << "Background ROI start" << std::endl; infoOut << BG_ROI[0] << std::endl; infoOut << "Background ROI stop" << std::endl; infoOut << BG_ROI[1] << std::endl; infoOut << "Signal pretrace start" << std::endl; infoOut << S_PT[0] << std::endl; infoOut << "Signal pretrace stop" << std::endl; infoOut << S_PT[1] << std::endl; infoOut << "Signal ROI start" << std::endl; infoOut << S_ROI[0] << std::endl; infoOut << "Signal ROI stop" << std::endl; infoOut << S_ROI[1] << std::endl; infoOut << "Unzipped file size" << std::endl; infoOut << fileSize << std::endl; infoOut << "SPE charge histogram" << std::endl; for (int idx = 0; idx < 300; idx++) { infoOut << spe_charge_dist[idx] << " "; } infoOut << std::endl; infoOut << "Background - Peaks in pretrace histogram" << std::endl; for (int idx = 0; idx < 52; idx++) { infoOut << bg_pe_pt[idx] << " "; } infoOut << std::endl; infoOut << "Signal - Peaks in pretrace histogram" << std::endl; for (int idx = 0; idx < 52; idx++) { infoOut << s_pe_pt[idx] << " "; } infoOut << std::endl; infoOut << "CsI baseline histogram" << std::endl; for (int idx = 0; idx < 32; idx++) { infoOut << baseline_hist[idx] << " "; } infoOut << std::endl; infoOut << "Peak width distribution" << std::endl; for (int idx = 0; idx < 51; idx++) { infoOut << peak_width_distribution[idx] << " "; } infoOut << std::endl; infoOut << "PE amplitudes" << std::endl; for (int idx = 0; idx < 100; idx++) { infoOut << peak_height_dist[idx] << " "; } infoOut << std::endl; infoOut << "Big pulse onsets" << std::endl; for (int idx = 0; idx < bP_onset_arr.size(); idx++) { infoOut << bP_onset_arr[idx] << " "; } infoOut << std::endl; infoOut << "Big pulse charges" << std::endl; for (int idx = 0; idx < bP_charge_arr.size(); idx++) { infoOut << bP_charge_arr[idx] << " "; } infoOut << std::endl; infoOut << "All muon onsets - If linear gate present only the first is recorded" << std::endl; for (int idx = 0; idx < muon_onset_arr.size(); idx++) { infoOut << muon_onset_arr[idx] << " "; } infoOut << std::endl; infoOut << "Charge distribution in full waveform" << std::endl; for (int idx_1 = 0; idx_1 < 350; idx_1++) { bool printLine = false; for (int idx_2 = 0; idx_2 < 350; idx_2++) { if (charge_distribution[idx_1][idx_2] > 0) { printLine = true; break; } } if (printLine) { infoOut << idx_1 << " "; for (int idx_2 = 0; idx_2 < 350; idx_2++) { if (charge_distribution[idx_1][idx_2] > 0) { infoOut << idx_2 << " " << charge_distribution[idx_1][idx_2] << " "; } } infoOut << std::endl; } } infoOut.close(); } return 0; }
static void itsaWriteMerged(struct chromInfo *chromList, DNA *allDna, bits32 *offsetArray, bits32 *listArray, bits32 *index13, char *output) /* Write out a file that contains a single splix that is the merger of * all of the individual splixes in list. As a side effect will replace * offsetArray with suffix array and listArray with traverse array */ { FILE *f = mustOpen(output, "w+"); /** Allocate header and fill out easy constant fields. */ struct itsaFileHeader *header; AllocVar(header); header->majorVersion = ITSA_MAJOR_VERSION; header->minorVersion = ITSA_MINOR_VERSION; /* Figure out sizes of names and sequence for each chromosome. */ struct chromInfo *chrom; bits32 chromNamesSize = 0; bits64 dnaDiskSize = 1; /* For initial zero. */ for (chrom = chromList; chrom != NULL; chrom = chrom->next) { chromNamesSize += strlen(chrom->name) + 1; dnaDiskSize += chrom->size + 1; /* Include separating zeroes. */ } /* Fill in most of rest of header fields */ header->chromCount = slCount(chromList); header->chromNamesSize = roundUpTo4(chromNamesSize); header->dnaDiskSize = roundUpTo4(dnaDiskSize); bits32 chromSizesSize = header->chromCount*sizeof(bits32); /* Write header. */ mustWrite(f, header, sizeof(*header)); /* Write chromosome names. */ for (chrom = chromList; chrom != NULL; chrom = chrom->next) mustWrite(f, chrom->name, strlen(chrom->name)+1); zeroPad(f, header->chromNamesSize - chromNamesSize); /* Write chromosome sizes. */ for (chrom = chromList; chrom != NULL; chrom = chrom->next) mustWrite(f, &chrom->size, sizeof(chrom->size)); int chromSizesSizePad = chromSizesSize - header->chromCount * sizeof(bits32); zeroPad(f, chromSizesSizePad); /* Write out chromosome DNA and zeros before, between, and after. */ mustWrite(f, allDna, dnaDiskSize); zeroPad(f, header->dnaDiskSize - dnaDiskSize); verboseTime(1, "Wrote %lld bases of DNA including zero padding", header->dnaDiskSize); /* Calculate and write suffix array. Convert index13 to index of array as opposed to index * of sequence. */ bits64 arraySize = 0; off_t suffixArrayFileOffset = ftello(f); int slotCount = itsaSlotCount; int slotIx; for (slotIx=0; slotIx < slotCount; ++slotIx) { int slotSize = finishAndWriteOneSlot(offsetArray, listArray, index13[slotIx], allDna, f); /* Convert index13 to hold the position in the suffix array where the first thing matching * the corresponding 13-base prefix is found. */ if (slotSize != 0) index13[slotIx] = arraySize+1; /* The +1 is so we can keep 0 for not found. */ else index13[slotIx] = 0; arraySize += slotSize; if ((slotIx % 200000 == 0) && slotIx != 0) { verboseDot(); if (slotIx % 10000000 == 0) verbose(1, "fine sort bucket %d of %d\n", slotIx, slotCount); } } verbose(1, "fine sort bucket %d of %d\n", slotCount, slotCount); verboseTime(1, "Wrote %lld suffix array positions", arraySize); /* Now we're done with the offsetArray and listArray buffers, so use them for the * next phase. */ bits32 *suffixArray = offsetArray; offsetArray = NULL; /* Help make some errors more obvious */ bits32 *traverseArray = listArray; listArray = NULL; /* Help make some errors more obvious */ /* Read the suffix array back from the file. */ fseeko(f, suffixArrayFileOffset, SEEK_SET); mustRead(f, suffixArray, arraySize*sizeof(bits32)); verboseTime(1, "Read suffix array back in"); /* Calculate traverse array and cursor arrays */ memset(traverseArray, 0, arraySize*sizeof(bits32)); UBYTE *cursorArray = needHugeMem(arraySize); itsaFillInTraverseArray(allDna, suffixArray, arraySize, traverseArray, cursorArray); verboseTime(1, "Filled in traverseArray"); /* Write out traverse array. */ mustWrite(f, traverseArray, arraySize*sizeof(bits32)); verboseTime(1, "Wrote out traverseArray"); /* Write out 13-mer index. */ mustWrite(f, index13, itsaSlotCount*sizeof(bits32)); verboseTime(1, "Wrote out index13"); /* Write out bits of cursor array corresponding to index. */ for (slotIx=0; slotIx<itsaSlotCount; ++slotIx) { bits32 indexPos = index13[slotIx]; if (indexPos == 0) fputc(0, f); else fputc(cursorArray[indexPos-1], f); } verboseTime(1, "Wrote out cursors13"); /* Update a few fields in header, and go back and write it out again with * the correct magic number to indicate it's complete. */ header->magic = ITSA_MAGIC; header->arraySize = arraySize; header->size = sizeof(*header) // header + header->chromNamesSize + // chromosome names + header->chromCount * sizeof(bits32) // chromosome sizes + header->dnaDiskSize // dna sequence + sizeof(bits32) * arraySize // suffix array + sizeof(bits32) * arraySize // traverse array + sizeof(bits32) * itsaSlotCount // index13 + sizeof(UBYTE) * itsaSlotCount; // cursors13 rewind(f); mustWrite(f, header, sizeof(*header)); carefulClose(&f); verbose(1, "Completed %s is %lld bytes\n", output, header->size); }
std::string encode(const std::string & word) const{ assert(!word.empty()); return zeroPad(upperFront(word)+ encodeDigits(word.substr(1))); }
std::string encode(const std::string& word) const { return zeroPad(upperFront(head(word)) + tail(encodedDigits(word))); }