Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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);
}
Ejemplo n.º 6
0
  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)));
 }