// --------------------------------------------------------- // // fiberQA_test.cc - test version of fiberQA.cc // // authors: richard.t.jones at uconn.edu, // version: april 26, 2014 // --------------------------------------------------------- #define TRIGGERED_BY_PULSER 1 #define ROW_SELECT_BY_EVENT_NUMBER 1 #include #include #include #include #include #include #include // root stuff #include #include #include #include "fiberQA.h" using namespace std; using namespace evio; int evtCount = 0; int totalRows = 0; int verbose_print = 0; int row_mode = 0; double sum_singles_high[10] = {0,0,0,0,0,0,0,0,0,0}; double sum_singles_low[10] = {0,0,0,0,0,0,0,0,0,0}; // prototypes void analyzeEvent(evioDOMTree &eventTree); void analyzeBank(evioDOMNodeP bankPtr); void initHistograms(const char* filename); void fillHistograms(); // Define bit masks // F1 bit masks #define F1_RAW_DATA 0xFF000000 int main(int argc, char **argv) { if (argc == 1) { printf("Usage: fiberQA \n"); exit(1); } char filename[128]; strcpy(filename, argv[1]); try { char fname[128],fname1[128]; sprintf(fname1,"%s",filename); strtok(fname1,"."); sprintf(fname,"%s.root",fname1); initHistograms(fname); cout << "open data file " << filename < STOP_AFTER_NEVENTS) { break; } #endif if (evtCount%10000 == 0) { cout << "fiberQA read " << evtCount << " events" << endl; } evioDOMTree eventTree(chan); analyzeEvent(eventTree); } chan.close(); ROOTfile->cd(); ROOTfile->Write(); ROOTfile->Close(); delete ROOTfile; cout<toString() << endl << endl; exit(EXIT_FAILURE); } cout << endl << endl << " ***fiberQA done after " << totalRows << " events analyzed***" << endl << endl; exit(EXIT_SUCCESS); } void analyzeEvent(evioDOMTree &eventTree) { evioDOMNodeListP bankList = eventTree.getNodeList(); for_each (bankList->begin(), bankList->end(), analyzeBank); } void analyzeBank(evioDOMNodeP bankPtr) { int SlotID = -1; int nboard = -1; int trigger_numb = -1; switch (bankPtr->tag) { case 0: // ignore break; case 3: // header bank { const vector *vec = bankPtr->getVector(); if (vec == NULL) { cerr << "?unable to get header bank vector" << endl; return; } if (verbose_print) { cout << dec << "found header bank: run number " << (*vec)[0] << endl << " event number " << (*vec)[1] << endl << endl; } break; } case 6: // F1TDC data block { const vector *vec = bankPtr->getVector(); if (vec == NULL) { cerr << "?unable to get tdc bank vector" << endl; return; } if (verbose_print) { cout << " -------------------" << endl; cout << " F1TDC Vector Size = " << vec->size() << endl; cout << " -------------------" << endl; } for (unsigned i = 0; i < vec->size(); i++){ if (verbose_print) { cout << hex << (*vec)[i] << dec << endl; } if ((*vec)[i] == 0xf1daffff) continue; unsigned int data_type = ((*vec)[i] & 0x800000) >> 23; if (verbose_print) { cout << " Data type = " << data_type << endl; } if (data_type == 0) { // Event header unsigned int event_number = ((*vec)[i] & 0x3f0000) >> 16; unsigned int trigger_time = ((*vec)[i] & 0xff80) >> 7; unsigned int trigger_fifo_overflow = ((*vec)[i] & 0x400000) >> 22; unsigned int f1_chip = ((*vec)[i] & 0x38) >> 3; unsigned int f1_chan = ((*vec)[i] & 0x7); if (verbose_print) { cout << "Event Header: Event number = " << event_number << " Trigger time = " << trigger_time << " Chip = " << f1_chip << " Channel = " << f1_chan << " Trigger FIFO overflow = " << trigger_fifo_overflow << endl; } } else if (data_type == 1) { // Data if (verbose_print) { cout << endl; } unsigned int slot_id = ((*vec)[i] & 0xF8000000) >> 27; unsigned int chip_res_locked = ((*vec)[i] & 0x4000000) >> 26; unsigned int fifo_overflows = ((*vec)[i] & 0x3000000) >> 24; unsigned int f1_chip = ((*vec)[i] & 0x380000) >> 19; unsigned int f1_chan = ((*vec)[i] & 0x70000) >> 16; unsigned int f1_time = ((*vec)[i] & 0xffff); if (verbose_print) { cout << "Data word: Slot ID = " << slot_id << " Chip = " << f1_chip << " Channel = " << f1_chan << " Resolution Locked = " << chip_res_locked << " FIFO overflows = " << fifo_overflows << " cTime = " << f1_time << endl; } if (chip_res_locked == 0) { cout << " FATAL: Chip Resolution is NOT locked " << "F1 CHIP = " << f1_chip << " Channel = " << f1_chan << endl; continue; } if (fifo_overflows != 0) { cout << " FATAL: FIFO overflows " << "F1 CHIP = " << f1_chip << " Channel = " << f1_chan << " FIFO overflow " << fifo_overflows << endl; continue; } if ( (f1_chip < 0) || (f1_chip > 7) ) { cout << "F1TDC: Wrong Chip Number " << f1_chip << endl; continue; } } } break; } case 5: // FADC data block { const vector *vec = bankPtr->getVector(); if (vec == NULL) { cerr << "?unable to get fadc bank vector" << endl; return; } unsigned int data_new_type = 0; unsigned int data_type = 0; int channel = -1 ; unsigned int time_stamp = 0; unsigned int pulse_number = -1; unsigned int first_sample = -1; if (verbose_print) { cout << " Vector Size = " << vec->size() << endl; } float adc[2] = {0,0}; for (unsigned i = 0; i < vec->size(); i++) { // Bank header // bit 31 = 1 // bits 27- 30 = 0 // bits 22 - 26 = SlotID // bits 11 - 21 = Number of events in block; bits 0 - 10 event block number if ( (*vec)[i] >> 27 == 0x10 ) { /* Bank header 1000 0 */ SlotID = ((*vec)[i] & 0x7c00000) >> 22; nboard++; if (verbose_print) { cout << " FADC found in slot: " << SlotID << endl; } } // Event header // bit 31 = 1 // bits 27- 30 = 0x1001 // bits 0 - 26 = Trigger number else if ( (*vec)[i] >> 27 == 0x12 ) { /* Event header 1001 0 */ trigger_numb = ((*vec)[i] & 0x7FFFFFF); if (verbose_print) { cout << " FADC found in slot: " << SlotID << " Trigger time " << trigger_numb << endl; } } else if ( (*vec)[i] & 0x80000000 ) { /* data type defining word */ data_type = ((*vec)[i] & 0x78000000) >> 27; // data_type == 4 - window raw data // data_type == 6 - pulse raw data data_new_type = 1; } else { data_new_type = 0; }; if (data_type == 4 ) { // window raw data if (data_new_type == 1) { unsigned int fadc_width = ((*vec)[i] & 0xFFF); channel = ((*vec)[i] & 0x7800000) >> 23; if (verbose_print) { cout << " Data Type = " << data_type << " Fadc_width = " << fadc_width << " Channel = " << channel << endl; } time_stamp = 1; } else { unsigned int valid_1 = 1; unsigned int valid_2 = 1; unsigned int adc_1 = ((*vec)[i] & 0x1FFF0000) >> 16; if ((*vec)[i] & 0x20000000) { valid_1 = 0; } unsigned int adc_2 = ((*vec)[i] & 0x1FFF); if ( (*vec)[i] & 0x2000 ) { valid_2 = 0; } adc[0] = (adc_1 < 4000)? float(adc_1) : 0; adc[1] = (adc_2 < 4000)? float(adc_2) : 0; if (verbose_print) { cout << " Time stamp = " << time_stamp << " Nboard = " << nboard << " SlotID = " << SlotID << " Channel = " << channel << " ADC1 = " << adc[0] << " " << adc[1] << endl; } if ((channel >= 0) && (channel < channels)) { fadc_raw[channel][time_stamp*2-2] = adc[0]; fadc_raw[channel][time_stamp*2-1] = adc[1]; } else { //cout << " Wrong channel number " << channel // << endl; exit(EXIT_FAILURE); } time_stamp++; } } else if (data_type == 6 ) { // raw pulse data if (data_new_type == 1) { channel = ((*vec)[i] & 0x7800000) >> 23; pulse_number = ((*vec)[i] & 0x600000) >> 21; first_sample = ((*vec)[i] & 0x3FF); if (verbose_print) { cout << endl; cout << " Data Type = " << data_type << " Channel = " << channel << " Pulse number = " << pulse_number << " First sample = " << first_sample << endl; cout << endl; } time_stamp = 1; } else { unsigned int valid_1 = -1; unsigned int valid_2 = -1; unsigned int adc_1 = ((*vec)[i] & 0x1FFF0000) >> 16; valid_1 = ((*vec)[i] & 0x20000000 ) >> 29; unsigned int adc_2 = ((*vec)[i] & 0x1FFF); valid_2 = ( (*vec)[i] & 0x2000 ) >> 13; float adc[2]; adc[0] = (adc_1 < 4000)? float(adc_1) : 0; adc[1] = (adc_2 < 4000)? float(adc_2) : 0; } time_stamp++; } if ( data_type == 7 ) { // Pulse Integral data channel = ((*vec)[i] & 0x7800000) >> 23; unsigned int pulse_numb = ((*vec)[i] & 0x200000) >> 21; unsigned int pulse_int = ((*vec)[i] & 0x3FFFF); if (verbose_print) { cout << " Channel = " << channel << " Pulse number = " << pulse_numb << " Pulse int = " << pulse_int << endl; } } } fillHistograms(); break; } default: { break; } } } void initHistograms(const char* fname) { ROOTfile = new TFile(fname,"RECREATE","new"); cout << "Opened ROOT file " << fname << " ..." << endl; ROOTfile->cd(); // histograms for individual fibers in high gain mode for (int id=1; id < 16; id++) { char name[10]; sprintf(name,"hhigh%d",id); char title[256]; sprintf(title,"fiber %d high gain from run %s",id,fname); hhigh[id] = new TH1D(name,title,8000,-5.,1995.); } // histograms for individual fibers in low gain mode (column 1 only) for (int id=1; id < 6; id++) { char name[10]; sprintf(name,"hlow%d",id); char title[256]; sprintf(title,"fiber %d low gain from run %s",id,fname); hlow[id] = new TH1D(name,title,400,-5.,95.); } // histograms for individual channels when all lit for (int id=1; id < 9; id++) { char name[10]; sprintf(name,"hall%d",id); char title[256]; sprintf(title,"channel %d from run %s",id,fname); if (id < 6) { hall[id] = new TH1D(name,title,100,-5.,245.); } else { hall[id] = new TH1D(name,title,8000,-5.,1995.); } } } void fillHistograms() { double pheight[channels]; pulse_analyzer pana(fadc_raw[0], channels, window_size); for (int channel=1; channel < 9; channel++) { #if TRIGGERED_BY_PULSER pheight[channel] = pana.pheight_trig_pulser(channel); #else pheight[channel] = pana.pheight_trig_summer(channel); #endif } #if ROW_SELECT_BY_EVENT_NUMBER int single_row_bounds[7][2] = {{0,0}, {16000,30000}, {56000,80000}, {90000,110000}, {126000,132000}, {145000,170000}, {200000,210000}}; for (int row=1; row < 6; ++row) { if (evtCount > single_row_bounds[row][0] && evtCount < single_row_bounds[row][1]) { hhigh[row]->Fill(pheight[6]); hhigh[row+5]->Fill(pheight[7]); hhigh[row+10]->Fill(pheight[8]); hlow[row]->Fill(pheight[row]); } } if (evtCount > single_row_bounds[6][0] && evtCount < single_row_bounds[6][1]) { for (int row=1; row < 9; ++row) { hall[row]->Fill(pheight[row]); } } #else double row_select_thresh = 10; double col_select_thresh = 50; int rows_hit = 0; for (int row=1; row < 6; ++row) { if (pheight[6] < row_select_thresh || pheight[row] < 1) { continue; } else if ((pheight[6] - pheight[row]*7.0)/pheight[6] < 0.15) { hhigh[row]->Fill(pheight[6]); hhigh[row+5]->Fill(pheight[7]); hhigh[row+10]->Fill(pheight[8]); hlow[row]->Fill(pheight[row]); sum_singles_high[row] += pheight[6]; sum_singles_low[row] += pheight[row]; rows_hit++; if (row != row_mode) { std::cout << "switching to single-row mode on row " << row << " at event " << evtCount << std::endl; std::cout << " pheight[1] = " << pheight[1] << std::endl; std::cout << " pheight[2] = " << pheight[2] << std::endl; std::cout << " pheight[3] = " << pheight[3] << std::endl; std::cout << " pheight[4] = " << pheight[4] << std::endl; std::cout << " pheight[5] = " << pheight[5] << std::endl; std::cout << " pheight[6] = " << pheight[6] << std::endl; std::cout << " pheight[7] = " << pheight[7] << std::endl; std::cout << " pheight[8] = " << pheight[8] << std::endl; row_mode = row; } } } if (rows_hit == 0 && pheight[6] > col_select_thresh && pheight[1] > 1 && pheight[2] > 1 && pheight[3] > 1 && pheight[4] > 1 && pheight[5] > 1) { if (row_mode < 6) { std::cout << "switching to multi-row mode" << " at event " << evtCount << std::endl; std::cout << " pheight[1] is " << pheight[1] << std::endl; std::cout << ", pheight[2] is " << pheight[2] << std::endl; std::cout << ", pheight[3] is " << pheight[3] << std::endl; std::cout << ", pheight[4] is " << pheight[4] << std::endl; std::cout << ", pheight[5] is " << pheight[5] << std::endl; std::cout << ", pheight[6] is " << pheight[6] << std::endl; std::cout << "sum_singles ratios are:" << std::endl << " [1] is " << sum_singles_low[1]/sum_singles_high[1] << std::endl << " [2] is " << sum_singles_low[2]/sum_singles_high[2] << std::endl << " [3] is " << sum_singles_low[3]/sum_singles_high[3] << std::endl << " [4] is " << sum_singles_low[4]/sum_singles_high[4] << std::endl << " [5] is " << sum_singles_low[5]/sum_singles_high[5] << std::endl; } for (int row=1; row < 9; ++row) { hall[row]->Fill(pheight[row]); } row_mode = 6; } else if (rows_hit > 1 && pheight[6] > col_select_thresh) { cout << "weird rows hit " << rows_hit << endl; cout << "pheight[6] is " << pheight[6] << endl; } else { totalRows += rows_hit; } #endif }