#ifdef CF__LINUX #include "SiUSBLib.h" #include #endif #ifdef __VISUALC__ #include "stdafx.h" #endif #include "ConfigRegister.h" #include "defines.h" #include #include #include #include #include using namespace std; ConfigRegister::ConfigRegister(SiUSBDevice * Handle, bool isFEI4B) { myUSB = Handle; FEI4B = isFEI4B; isCalMode = 0; isTOTMode = 0; total_trigger_counter = 0; total_valid_bcid_window = 0; total_no_dr_counter = 0; total_dr_counter = 0; total_hit_counter = 0; total_dh_counter = 0; m_lengthLVL1 = 0; total_processing_time = 0; current_phaseshift = 0; } //ConfigRegister::~ConfigRegister(); int ConfigRegister::ReadRegister(int CS) { QMutexLocker locker(myUSB->getMutex()); if ((CS < 64) && (CS >= 0)) { unsigned char data; myUSB->ReadXilinx((unsigned short)CS, &data, 1); return (int)data; } else { return -1; } } void ConfigRegister::WriteRegister(int CS, int data) { QMutexLocker locker(myUSB->getMutex()); if ((CS < 64) && (CS >= 0) && (data < 256) && (data >= 0)) { unsigned char tmp_data; tmp_data = (unsigned char) data; myUSB->WriteXilinx((unsigned short) CS, &tmp_data, 1); } } void ConfigRegister::SetCableLengthReg(int value) { WriteRegister(CS_CABLE_LENGTH, value); } void ConfigRegister::GetSystemMode(bool &CalMode, bool &TOTMode) { CalMode = isCalMode; TOTMode = isTOTMode; } void ConfigRegister::SetUSBHandle(SiUSBDevice * Handle) { myUSB = Handle; } void ConfigRegister::ResetAll() { WriteRegister(CS_RESET_ALL, 1); } void ConfigRegister::WriteStrbSave(unsigned char *data) { QMutexLocker locker(myUSB->getMutex()); myUSB->WriteExternal(CS_L_STRB, data, 7); } void ConfigRegister::WriteStrbStart() { WriteRegister(CS_TRIGGER_STRB_LV1, 1); } void ConfigRegister::WriteStrbStop() { // if qty == 0, Setting CS_TRIGGER_STRB_LV1 does not stop the FSM. int quantity = ReadRegister(CS_QUANTITY); if (quantity == 0) { WriteStrbQuantity(1); #ifdef CF__LINUX usleep(100000); #else Sleep(100); #endif WriteStrbQuantity(0); } else WriteRegister(CS_TRIGGER_STRB_LV1, 0); } void ConfigRegister::WriteStrbQuantity(int value) { WriteRegister(CS_QUANTITY, value); } void ConfigRegister::SetCalibrationMode() { int temp; temp = ReadRegister(CS_SYSTEM_CONF); if (temp == -1) return; temp &= ~0x03; // clear bits temp |= 0x01; // set bits WriteRegister(CS_SYSTEM_CONF, temp); isCalMode = 1; isTOTMode = 0; } void ConfigRegister::SetTOTMode() { int temp; temp = ReadRegister(CS_SYSTEM_CONF); if (temp == -1) return; temp &= ~0x03; // clear bits temp |= 0x02; // set bits WriteRegister(CS_SYSTEM_CONF, temp); isCalMode = 0; isTOTMode = 1; } void ConfigRegister::SetRunMode() { int temp; temp = ReadRegister(CS_SYSTEM_CONF); if (temp == -1) return; temp &= ~0x03; // clear bits WriteRegister(CS_SYSTEM_CONF, temp); isCalMode = 0; isTOTMode = 0; } void ConfigRegister::SetTLUMode() { int temp; temp = ReadRegister(CS_SYSTEM_CONF); if (temp == -1) return; temp |= 0x03; // set bits WriteRegister(CS_SYSTEM_CONF, temp); isCalMode = 1; isTOTMode = 1; } void ConfigRegister::enable_8b10_Decoding() { int temp; temp = ReadRegister(CS_SYSTEM_CONF); if (temp == -1) return; temp &= ~0x20; // clear bit WriteRegister(CS_SYSTEM_CONF, temp); } void ConfigRegister::disable_8b10_Decoding() { int temp; temp = ReadRegister(CS_SYSTEM_CONF); if (temp == -1) return; temp |= 0x20; // set bit WriteRegister(CS_SYSTEM_CONF, temp); } // outdated, to use other trigger modes wirte directly to the register void ConfigRegister::enableExtLV1() { setTriggerMode(2); // old: int temp; temp = ReadRegister(CS_SYSTEM_CONF); if (temp == -1) return; temp |= 0x10; // set bit WriteRegister(CS_SYSTEM_CONF, temp); } void ConfigRegister::disableExtLV1() { int temp1 = 0x00; // clear bit WriteRegister(CS_TRIGGER_MODE, temp1); //old: int temp; temp = ReadRegister(CS_SYSTEM_CONF); if (temp == -1) return; temp &= ~0x10; // clear bit WriteRegister(CS_SYSTEM_CONF, temp); } void ConfigRegister::setTriggerMode(int TriggerMode) { int temp; temp = ReadRegister(CS_TRIGGER_MODE); if (TriggerMode==5) { //remove trigger replication master flag temp = (TriggerMode & 0x0F); } else { // leave trigger replication master flag untouched temp = (temp & 0xF0) | (TriggerMode & 0x0F); } WriteRegister(CS_TRIGGER_MODE, temp); } void ConfigRegister::enableTriggerReplicationMaster() { int temp; temp = ReadRegister(CS_TRIGGER_MODE); if ((temp & 0x0F) == 5) return; // Device is replication slave! // leave trigger mode untouched temp = 0x10 | (temp & 0x0F); WriteRegister(CS_TRIGGER_MODE, temp); } void ConfigRegister::disableTriggerReplicationMaster() { int temp; temp = ReadRegister(CS_TRIGGER_MODE); // leave trigger mode untouched temp = (temp & 0x0F); WriteRegister(CS_TRIGGER_MODE, temp); } void ConfigRegister::enableCMDLV1() { int temp; temp = ReadRegister(CS_SYSTEM_CONF); if (temp == -1) return; temp &= ~0x04; // clear bit WriteRegister(CS_SYSTEM_CONF, temp); } void ConfigRegister::disableCMDLV1() { int temp; temp = ReadRegister(CS_SYSTEM_CONF); if (temp == -1) return; temp |= 0x04; // set bit WriteRegister(CS_SYSTEM_CONF, temp); } void ConfigRegister::enable_160Mbps_data_rate() { int temp; temp = ReadRegister(CS_SYSTEM_CONF); if (temp == -1) return; temp |= 0x40; // set bit WriteRegister(CS_SYSTEM_CONF, temp); } void ConfigRegister::disable_160Mbps_data_rate() { int temp; temp = ReadRegister(CS_SYSTEM_CONF); if (temp == -1) return; temp &= ~0x40; // clear bit WriteRegister(CS_SYSTEM_CONF, temp); } void ConfigRegister::EnablePowerChannel(bool on_off, int channel) { int temp; temp = ReadRegister(CS_POWER_CONTROL); if (temp == -1) return; if (on_off == true) temp |= (0x01 << channel); // set bit else temp &= ~(0x01 << channel); // clear bit WriteRegister(CS_POWER_CONTROL, temp); } void ConfigRegister::stopXCK(bool status) { int temp; temp = ReadRegister(CS_SYSTEM_CONF); if (temp == -1) return; if (status == true) temp |= 0x80; // set bit else temp &= ~0x80; // clear bit WriteRegister(CS_SYSTEM_CONF, temp); } void ConfigRegister::SetAuxClkFreq(int freq) { WriteRegister(CS_AUXCLK_FREQ, freq); } void ConfigRegister::incr_phase_shift() { WriteRegister(CS_PS_CONTROL, 3); current_phaseshift++; } void ConfigRegister::decr_phase_shift() { WriteRegister(CS_PS_CONTROL, 1); current_phaseshift--; } bool ConfigRegister::check_phase_shift_overflow() { int temp; temp = ReadRegister(CS_MEAS_STATUS); if ((temp & 0x04) == 0x04) return true; else return false; } double ConfigRegister::StartSyncCheck(double min_BitErrorRate) { double BitErrorRate = 1; int data = 0x02; int errors = 0; double count = 1; int newerrors = 0; WriteRegister(CS_CONTROL_PATTERN, data); // reset pattern... data = 0x01; while ((BitErrorRate > min_BitErrorRate)) { WriteRegister(CS_START_SYNC_CHECK, data); newerrors = ReadRegister(CS_READ_SYNC_ERRORS_LOW); newerrors = newerrors + ((ReadRegister(CS_READ_SYNC_ERRORS_HIGH) & 0xff) << 8); errors = errors + newerrors; if (errors != 0) BitErrorRate = errors / (count * 10000); else BitErrorRate = 1 / (count * 10000); count++; if (errors > 100) break; } return BitErrorRate; } bool ConfigRegister::StartSyncScan(double min_BitErrorRate) { double BitErrorRate = 0; bool overflow = false; int best_phaseshift = 0; int count = 0; bool NegEdgeFound = false; bool PosEdgeFound = false; bool EFRFound = false; bool scan_succeeded = false; int countout = 0; while (!scan_succeeded && countout < 10) { countout++; count = 0; NegEdgeFound = false; PosEdgeFound = false; EFRFound = false; //for (int i = 0; i < 201; i++) // SyncScanResultsY[i] = 1; for (int i = 0; i < 201; i++) { SyncScanResultsY[i] = 0; SyncScanResultsX[i] = 0; } // go to point phaseshift point NULL while (current_phaseshift != 0) { if(current_phaseshift < 0) incr_phase_shift(); else if (current_phaseshift > 0) decr_phase_shift(); else break; } // search for point with min_BitErrorRate in alternating directions bool SearchNegDirection = true; BitErrorRate = StartSyncCheck(min_BitErrorRate); int SearchNumber = 1; while ((myUSB->HandlePresent()) && (BitErrorRate > min_BitErrorRate) && (overflow == false)) { overflow = check_phase_shift_overflow(); if (SearchNegDirection) { for (int i = 0; i < SearchNumber * 10; i++) incr_phase_shift(); //decr_phase_shift(); SearchNegDirection = false; } else { for (int i = 0; i < SearchNumber * 10; i++) decr_phase_shift(); SearchNegDirection = true; } SearchNumber++; BitErrorRate = StartSyncCheck(min_BitErrorRate); } // go out of overflow while (myUSB->HandlePresent() && overflow) { if (current_phaseshift >= 0) decr_phase_shift(); else incr_phase_shift(); overflow = check_phase_shift_overflow(); } // search for negedge while ((myUSB->HandlePresent()) && (BitErrorRate < 0.005) && (overflow == false)) { decr_phase_shift(); BitErrorRate = StartSyncCheck(min_BitErrorRate/*0.001*/); overflow = check_phase_shift_overflow(); } if ((BitErrorRate >= 0.001) && (overflow == false) ) NegEdgeFound = true; // go out of overflow while (myUSB->HandlePresent() && overflow) { if (current_phaseshift >= 0) decr_phase_shift(); else incr_phase_shift(); overflow = check_phase_shift_overflow(); } //for (int i = 1; i <= 5; i++) // go out of negedge //{ // incr_phase_shift(); // BitErrorRate = StartSyncCheck(min_BitErrorRate); // count++; // SyncScanResultsY[count] = BitErrorRate; // SyncScanResultsX[count] = current_phaseshift; //} // Measure scanpoint 0 BitErrorRate = StartSyncCheck(min_BitErrorRate); SyncScanResultsY[count] = BitErrorRate; SyncScanResultsX[count] = current_phaseshift; // go out of negedge BitErrorRate = 0; while (myUSB->HandlePresent() && (BitErrorRate > min_BitErrorRate) && (count <= 195) && (overflow == false)) { incr_phase_shift(); overflow = check_phase_shift_overflow(); BitErrorRate = StartSyncCheck(min_BitErrorRate); count++; SyncScanResultsY[count] = BitErrorRate; SyncScanResultsX[count] = current_phaseshift; } if ((BitErrorRate <= min_BitErrorRate) && (overflow == false) ) EFRFound = true; BitErrorRate = 0; while ((myUSB->HandlePresent()) && (BitErrorRate <= 0.005) && (count <= 195) && (overflow == false)) // search for endpoint { incr_phase_shift(); overflow = check_phase_shift_overflow(); BitErrorRate = StartSyncCheck(min_BitErrorRate); count++; SyncScanResultsY[count] = BitErrorRate; SyncScanResultsX[count] = current_phaseshift; } if ((BitErrorRate >= 0.001) && (overflow == false) ) PosEdgeFound = true; best_phaseshift = current_phaseshift - (int)(count / 2); while (current_phaseshift != best_phaseshift) // set phaseshift to optimal value { if(current_phaseshift < best_phaseshift) incr_phase_shift(); else if (current_phaseshift > best_phaseshift) decr_phase_shift(); else break; } BitErrorRate = StartSyncCheck(min_BitErrorRate); scan_succeeded = NegEdgeFound && PosEdgeFound && EFRFound && (BitErrorRate <= min_BitErrorRate); } return scan_succeeded; } void ConfigRegister::StoreSyncCheckPattern() { WriteRegister(CS_CONTROL_PATTERN, 0x01); } void ConfigRegister::ResetSyncCheckPattern() { WriteRegister(CS_CONTROL_PATTERN, 0x02); } void ConfigRegister::ResetSRAMCounter() { WriteRegister(CS_SELADD0, 0); WriteRegister(CS_SELADD1, 0); WriteRegister(CS_SELADD2, 0); } void ConfigRegister::SetSRAMCounter(int StartAdd) { if (StartAdd >= 0) { WriteRegister(CS_SELADD0, (0xff & StartAdd)); WriteRegister(CS_SELADD1, (0xff & (StartAdd >> 8))); WriteRegister(CS_SELADD2, (0xff & (StartAdd >> 16))); } } void ConfigRegister::ReadSRAM() { // set address for high-speed interface ResetSRAMCounter(); // clear SRAMdataRB[i] for (int i = 0; i < SRAM_BYTESIZE; i++) SRAMdataRB[i] = 0x00; QMutexLocker locker(myUSB->getMutex()); // high-speed read myUSB->ReadBlock(SRAMdataRB, SRAM_BYTESIZE); locker.unlock(); if (isCalMode == true && isTOTMode == false) // calib mode { MakeConfHisto(0); } else if (isTOTMode == true && isCalMode == false) // ToT mode { MakeTOTHisto(); } else // run mode { BuildWords(); // debugging //WriteSRAMBitsFromWords("SRAMwords.raw"); //WriteSRAMWords("SRAMbits.raw"); } } void ConfigRegister::ReadSRAM(int scan_nr) { // set address for high-speed interface ResetSRAMCounter(); // clear SRAMdataRB[i] for (int i = 0; i < SRAM_BYTESIZE; i++) SRAMdataRB[i] = 0x00; QMutexLocker locker(myUSB->getMutex()); // high-speed read myUSB->ReadBlock(SRAMdataRB, SRAM_BYTESIZE); locker.unlock(); if (isCalMode == true && isTOTMode == false) // calib mode { //if (scan_nr == 0) // ClearConfHisto(); MakeConfHisto(scan_nr); // debugging //WriteSRAMBytes("ConfHisto.raw"); } else if (isTOTMode == true && isCalMode == false) // ToT mode { MakeTOTHisto(); // debugging //WriteSRAMBytes("ToTHisto.raw"); } else // run mode { BuildWords(); // debugging //WriteSRAMBitsFromWords("SRAMwords.raw"); //WriteSRAMWords("SRAMbits.raw"); } } void ConfigRegister::ReadSRAM(int StartAdd, int NumberOfWords) { if ((StartAdd >= 0) && (StartAdd < SRAM_BYTESIZE) && (StartAdd%WORDSIZE == 0) && (NumberOfWords > 0) && (NumberOfWords <= ((SRAM_WORDSIZE) - (StartAdd/WORDSIZE)))) { // set address for high-speed interface SetSRAMCounter(StartAdd); // clear SRAMdataRB[i] for (int i = 0; i < SRAM_BYTESIZE; i++) SRAMdataRB[i] = 0x00; QMutexLocker locker(myUSB->getMutex()); // high-speed read myUSB->ReadBlock(SRAMdataRB, (NumberOfWords * WORDSIZE)); locker.unlock(); if (isCalMode == true && isTOTMode == false) // calib mode { MakeConfHisto(0); } else if (isTOTMode == true && isCalMode == false) // ToT mode { MakeTOTHisto(); } else // run mode { BuildWords(); } } } void ConfigRegister::ClearSRAM() { // set address for high-speed interface ResetSRAMCounter(); // clear SRAMdataRB[i] for (int i = 0; i < SRAM_BYTESIZE; i++) SRAMdataRB[i] = 0x00; // clear SRAMwordsRB[i] for (int i = 0; i < SRAM_WORDSIZE; i++) SRAMwordsRB[i] = 0x00000000; // clear SRAMdata[i] for (int i = 0; i < SRAM_BYTESIZE; i++) SRAMdata[i] = 0x00; QMutexLocker locker(myUSB->getMutex()); // high-speed write myUSB->WriteBlock(SRAMdata, SRAM_BYTESIZE); locker.unlock(); // reset SRAM address for run mode readout resetRunModeAdd(); } void ConfigRegister::WriteSRAM(int StartAdd, int NumberOfWords) { if ((StartAdd >= 0) && (StartAdd < SRAM_BYTESIZE) && (StartAdd%WORDSIZE == 0) && (NumberOfWords > 0) && (NumberOfWords <= ((SRAM_WORDSIZE) - (StartAdd/WORDSIZE)))) { // set address for high-speed interface SetSRAMCounter(StartAdd); for (int i = 0; i < SRAM_BYTESIZE; i++) { SRAMdata[i] = 0xff; } QMutexLocker locker(myUSB->getMutex()); myUSB->WriteBlock(SRAMdata, (NumberOfWords * WORDSIZE)); } } void ConfigRegister::resetRunModeAdd() { WriteRegister(CS_RESET_ADD, 0x01); } // writing FE-I4 source scan raw data // new raw data format // // new_file == true: overwrite existing file, add timestamp at the beginning // close_file == true: add extra information at end of file (LVL1 histogram, processing time, timestamp) // fillSourceScanHistograms == true: fill source scan histograms that do not need clustering, append LV1 histogram at the end of file // fillClusterHistograms == true: fill source scan histograms that need clustering bool ConfigRegister::WriteFileFromRawData(std::string filename, bool new_file, bool close_file, bool fillSourceScanHistograms, bool fillClusterHistograms, int max_cluster_col_distance, int max_cluster_row_distance, int max_cluster_depth, int timewalk_threshold_max) { //FileSaveRB("debug_data.raw", SRAM_WORDSIZE, !new_file); if ((!isCalMode && isTOTMode) || (isCalMode && !isTOTMode)) { return false; } if ((m_lengthLVL1 < 1) || (m_lengthLVL1 > 16)) { return false; } #ifdef __VISUALC__ long int start = 0, stop = 0; #endif #ifdef CF__LINUX timeval start, stop; start.tv_sec=0; start.tv_usec=0; stop.tv_sec=0; stop.tv_usec=0; #endif ofstream fout; if (!filename.empty()) { // measure execution time #ifdef __VISUALC__ start = GetTickCount(); //long int stop = 0; #endif #ifdef CF__LINUX gettimeofday(&start, 0); #endif if (new_file == false) { fout.open(filename.c_str(), ios::app); // append data to existing file } else { fout.open(filename.c_str(), ios::out); // overwrite existing file } if (!fout.is_open()) // fails to open file return false; // create timestamp at begin of measurement if (new_file == true) { //time_t start_time; //time(&start_time); char timebuf[26]; #ifdef __VISUALC__ ctime_s(timebuf, 26, &start_time); #else // CF__LINUX ctime_r(&start_time, timebuf); #endif // __VISUALC__ fout << "#" << endl << "# " << string(timebuf) << "#" << endl; } // data processing //fout.setf(ios_base::showbase); // show 0x prefix for hex } if (new_file == true) { total_trigger_counter = 0; total_valid_bcid_window = 0; total_no_dr_counter = 0; total_dr_counter = 0; total_hit_counter = 0; total_dh_counter = 0; total_processing_time = 0; bcid_window_trigger_number = 0; } int bcid_window_start = 0; int bcid_window_end = 0; int bcid_window_dr_counter = 0; // counter for data records within one BCID window int bcid_window_dh_counter = 0; // counter for data headers within one BCID window int dr_counter = 0; int dh_counter = 0; int bcid_window_lv1id; // constant number within one BCID window int bcid_window_bcid; // consecutive number within one BCID window bool valid_bcid_window = true; bool valid_lv1id = true; bool valid_bcid = true; bool valid_data = true; bool valid_trigger_number = true; // *** CLUSTER CODE *** int cluster_size = 0; int cluster_tot = 0; int cluster_collision = 0; int total_cluster_collision = 0; int seed_col = 0; int seed_row = 0; int seed_eoe = 0; int bcid_window_cluster_counter = 0; // *** CLUSTER CODE *** // find next trigger number (end of BCID window), preprocessing BCID window for (int i = 0; i < (SRAM_WORDSIZE); i++) { bcid_window_end = i; if (DATA_HEADER_MACRO(SRAMwordsRB[i])) // data header { bcid_window_dh_counter++; if (bcid_window_dh_counter > m_lengthLVL1) { valid_bcid_window = false; } if (bcid_window_dh_counter == 1) // first data header in BCID window { if (!FEI4B) { bcid_window_lv1id = DATA_HEADER_LV1ID_MACRO(SRAMwordsRB[i]); // getting LV1ID from first data header bcid_window_bcid = DATA_HEADER_BCID_MACRO(SRAMwordsRB[i]); // getting BCID to start with } else { bcid_window_lv1id = DATA_HEADER_LV1ID_MACRO_FEI4B(SRAMwordsRB[i]); // getting LV1ID from first data header bcid_window_bcid = DATA_HEADER_BCID_MACRO_FEI4B(SRAMwordsRB[i]); // getting BCID to start with } } else { bcid_window_bcid++; if (bcid_window_bcid > 255) { bcid_window_bcid = 0; } if (!FEI4B) { if (bcid_window_lv1id != DATA_HEADER_LV1ID_MACRO(SRAMwordsRB[i])) { valid_lv1id = false; valid_bcid_window = false; } } else { if (bcid_window_lv1id != DATA_HEADER_LV1ID_MACRO_FEI4B(SRAMwordsRB[i])) { valid_lv1id = false; valid_bcid_window = false; } } if (!FEI4B) { if (bcid_window_bcid != DATA_HEADER_BCID_MACRO(SRAMwordsRB[i])) { valid_bcid = false; valid_bcid_window = false; } } else { if (bcid_window_bcid != DATA_HEADER_BCID_MACRO_FEI4B(SRAMwordsRB[i])) { valid_bcid = false; valid_bcid_window = false; } } } } else if (DATA_RECORD_MACRO(SRAMwordsRB[i])) // data record { bcid_window_dr_counter++; if ((DATA_RECORD_TOT1_MACRO(SRAMwordsRB[i]) == 0xF) || (DATA_RECORD_COLUMN1_MACRO(SRAMwordsRB[i]) < 1) || (DATA_RECORD_COLUMN1_MACRO(SRAMwordsRB[i]) > 80) || (DATA_RECORD_ROW1_MACRO(SRAMwordsRB[i]) < 1) || (DATA_RECORD_ROW1_MACRO(SRAMwordsRB[i]) > 336)) { valid_bcid_window = false; } if ((DATA_RECORD_TOT2_MACRO(SRAMwordsRB[i]) != 0xF) && ((DATA_RECORD_COLUMN2_MACRO(SRAMwordsRB[i]) < 1) || (DATA_RECORD_COLUMN2_MACRO(SRAMwordsRB[i]) > 80) || (DATA_RECORD_ROW2_MACRO(SRAMwordsRB[i]) < 1) || (DATA_RECORD_ROW2_MACRO(SRAMwordsRB[i]) > 336))) { valid_bcid_window = false; } } else if (TRIGGER_WORD_MACRO(SRAMwordsRB[i]) && (i > bcid_window_start) && (i < (SRAM_WORDSIZE-1))) // trigger word { total_trigger_counter++; if ((total_trigger_counter != 1) && (bcid_window_trigger_number != 0) && (TRIGGER_NUMBER_MACRO2(SRAMwordsRB[bcid_window_end], SRAMwordsRB[bcid_window_end+1]) != (bcid_window_trigger_number + 1))) { valid_bcid_window = false; } bcid_window_trigger_number = TRIGGER_NUMBER_MACRO2(SRAMwordsRB[bcid_window_end], SRAMwordsRB[bcid_window_end+1]); // defining valid BCID window if ((bcid_window_dh_counter == m_lengthLVL1) && !TRIGGER_ERROR_OCCURRED_MACRO(SRAMwordsRB[bcid_window_end]) && (valid_lv1id == true) && (valid_bcid == true) && (valid_data == true)) { valid_bcid_window = true; total_valid_bcid_window++; if (bcid_window_dr_counter == 0) { total_no_dr_counter++; } } else { valid_bcid_window = false; } if (!filename.empty()) fout << "0x" << std::setfill('0') << std::setw(6) << std::hex << SRAMwordsRB[bcid_window_end] << std::dec << std::setfill(' ') << endl; // trigger number if (!filename.empty()) fout << "0x" << std::setfill('0') << std::setw(6) << std::hex << SRAMwordsRB[bcid_window_end+1] << std::dec << std::setfill(' ') << endl; // trigger number if (!filename.empty()) fout << "TD" << /*std::setw(2)*/" " << TRIGGER_MODE_MACRO(SRAMwordsRB[bcid_window_end]) << /*std::setw(3)*/" " << TRIGGER_ERROR_MACRO(SRAMwordsRB[bcid_window_end]) << /*std::setw(11)*/" " << TRIGGER_NUMBER_MACRO2(SRAMwordsRB[bcid_window_end], SRAMwordsRB[bcid_window_end+1]) << endl; // trigger mode, error code, trigger number // debugging if (valid_bcid_window == false) { if (!filename.empty()) fout << "ERROR: BCID WINDOW NOT VALID" << endl; if (valid_trigger_number == false) { if (!filename.empty()) fout << "ERROR: TRIGGER NUMBER ERROR" << endl; } if (valid_data == false) { if (!filename.empty()) fout << "ERROR: UNKNOWN DATA WORD" << endl; } if (TRIGGER_ERROR_OCCURRED_MACRO(SRAMwordsRB[bcid_window_end])) { if (!filename.empty()) fout << "ERROR: TRIGGER DATA ERROR FLAG" << endl; } if (bcid_window_dh_counter != m_lengthLVL1) { if (!filename.empty()) fout << "ERROR: WRONG NUMBER OF DATA HEADERS" << endl; } if (valid_lv1id == false) { if (!filename.empty()) fout << "ERROR: LV1ID" << endl; } if (valid_bcid == false) { if (!filename.empty()) fout << "ERROR: BCID" << endl; } } if (bcid_window_dr_counter == 0) { if (!filename.empty()) fout << "WARNING: NO DATA RECORDS" << endl; } // *** CLUSTER CODE *** // clear arrays every new BCID window if (fillClusterHistograms == true) { bcid_window_cluster_counter = 0; total_cluster_collision = 0; for (int col = 0; col < 80; col++) { for (int row = 0; row < 336; row++) { for (int eoe = 0; eoe < 16; eoe++) { bcid_window_tot_array[col][row][eoe] = 0; bcid_window_hit_array[col][row][eoe] = false; bcid_window_hit_cluster_number[col][row][eoe] = 0; bcid_window_seed_cluster_number[col][row][eoe] = 0; bcid_window_hit_collision_cluster_number[col][row][eoe] = 0; } } } } // *** CLUSTER CODE *** // loop through BCID window for (int j = bcid_window_start; j < bcid_window_end; j++) { if (DATA_HEADER_MACRO(SRAMwordsRB[j])) // data header { if (!filename.empty()) fout << "0x" << std::setfill('0') << std::setw(6) << std::hex << SRAMwordsRB[j] << std::dec << std::setfill(' ') << endl; if (!FEI4B) if (!filename.empty()) fout << "DH" << /*std::setw(2)*/" " << DATA_HEADER_FLAG_MACRO(SRAMwordsRB[j]) << /*std::setw(4)*/" " << DATA_HEADER_LV1ID_MACRO(SRAMwordsRB[j]) << /*std::setw(4)*/" " << DATA_HEADER_BCID_MACRO(SRAMwordsRB[j]) << endl; else if (!filename.empty()) fout << "DH" << /*std::setw(2)*/" " << DATA_HEADER_FLAG_MACRO(SRAMwordsRB[j]) << /*std::setw(4)*/" " << DATA_HEADER_LV1ID_MACRO_FEI4B(SRAMwordsRB[j]) << /*std::setw(4)*/" " << DATA_HEADER_BCID_MACRO_FEI4B(SRAMwordsRB[j]) << endl; if (valid_bcid_window == true) // counting data header only if BCID window is valid { total_dh_counter++; } dh_counter++; dr_counter = 0; } else if (DATA_RECORD_MACRO(SRAMwordsRB[j])) // data record { if (!filename.empty()) fout << "0x" << std::setfill('0') << std::setw(6) << std::hex << SRAMwordsRB[j] << std::dec << std::setfill(' ') << endl; if (!filename.empty()) fout << "DR" << /*std::setw(4)*/" " << DATA_RECORD_COLUMN1_MACRO(SRAMwordsRB[j]) << /*std::setw(4)*/" " << DATA_RECORD_ROW1_MACRO(SRAMwordsRB[j]) << /*std::setw(3)*/" " << DATA_RECORD_TOT1_MACRO(SRAMwordsRB[j]);/* << endl;*/ // first hit //if (DATA_RECORD_TOT2_MACRO(SRAMwordsRB[j]) != 0xF) // paired hit //{ if (!filename.empty()) fout << /*std::setw(3)*/" " << DATA_RECORD_TOT2_MACRO(SRAMwordsRB[j]) << endl; // append second hit //first hit if (DATA_RECORD_TOT1_MACRO(SRAMwordsRB[j]) == 0xF) { if (!filename.empty()) fout << "ERROR: ToT(1) equal to 0xF" << endl; } if ((DATA_RECORD_COLUMN1_MACRO(SRAMwordsRB[j]) < 1) || (DATA_RECORD_COLUMN1_MACRO(SRAMwordsRB[j]) > 80)) { if (!filename.empty()) fout << "ERROR: COLUMN(1) OUT OF RANGE" << endl; } if ((DATA_RECORD_ROW1_MACRO(SRAMwordsRB[j]) < 1) || (DATA_RECORD_ROW1_MACRO(SRAMwordsRB[j]) > 336)) { if (!filename.empty()) fout << "ERROR: ROW(1) OUT OF RANGE" << endl; } // second hit if ((DATA_RECORD_COLUMN2_MACRO(SRAMwordsRB[j]) < 1) || (DATA_RECORD_COLUMN2_MACRO(SRAMwordsRB[j]) > 80)) { if (!filename.empty()) fout << "ERROR: COLUMN(2) OUT OF RANGE" << endl; } if ((DATA_RECORD_ROW2_MACRO(SRAMwordsRB[j]) < 1) || (DATA_RECORD_ROW2_MACRO(SRAMwordsRB[j]) > 336)) { if (!filename.empty()) fout << "ERROR: ROW(2) OUT OF RANGE" << endl; } if (valid_bcid_window == true) // counting hits / data records only if BCID window is valid { total_dr_counter += 1; if (DATA_RECORD_TOT1_MACRO(SRAMwordsRB[j]) <= 14) // first hit. We want to see all hits the chip sends... { total_hit_counter += 1; if (fillSourceScanHistograms == true) { // is getting filled in seperate function, that is always called //HitLV1HistoFromRawData[(dh_counter-1)] += 1; //HitTOTHistoFromRawData[DATA_RECORD_COLUMN1_MACRO(SRAMwordsRB[j])-1][DATA_RECORD_ROW1_MACRO(SRAMwordsRB[j])-1][DATA_RECORD_TOT1_MACRO(SRAMwordsRB[j])] += 1; //HitHistoFromRawData[DATA_RECORD_COLUMN1_MACRO(SRAMwordsRB[j])-1][DATA_RECORD_ROW1_MACRO(SRAMwordsRB[j])-1] += 1; } // *** CLUSTER CODE *** if ((fillClusterHistograms == true) && (DATA_RECORD_TOT1_MACRO(SRAMwordsRB[j]) <= 13)) // Cluster hits only for Tot <= 13) { if (bcid_window_hit_array[DATA_RECORD_COLUMN1_MACRO(SRAMwordsRB[j])-1][DATA_RECORD_ROW1_MACRO(SRAMwordsRB[j])-1][(dh_counter-1)] == true) { if (!filename.empty()) fout << "ERROR: LOCATION CONFLICT" << endl; } bcid_window_tot_array[DATA_RECORD_COLUMN1_MACRO(SRAMwordsRB[j])-1][DATA_RECORD_ROW1_MACRO(SRAMwordsRB[j])-1][(dh_counter-1)] = DATA_RECORD_TOT1_MACRO(SRAMwordsRB[j]); bcid_window_hit_array[DATA_RECORD_COLUMN1_MACRO(SRAMwordsRB[j])-1][DATA_RECORD_ROW1_MACRO(SRAMwordsRB[j])-1][(dh_counter-1)] = true; } // *** CLUSTER CODE *** } if (DATA_RECORD_TOT2_MACRO(SRAMwordsRB[j]) <= 14) // second hit. We want to see ALL hits the chip sends us... { total_hit_counter += 1; if (fillSourceScanHistograms == true) { // is getting filled in seperate function that is always called //HitLV1HistoFromRawData[(dh_counter-1)] += 1; //HitTOTHistoFromRawData[DATA_RECORD_COLUMN2_MACRO(SRAMwordsRB[j])-1][DATA_RECORD_ROW2_MACRO(SRAMwordsRB[j])-1][DATA_RECORD_TOT2_MACRO(SRAMwordsRB[j])] += 1; //HitHistoFromRawData[DATA_RECORD_COLUMN2_MACRO(SRAMwordsRB[j])-1][DATA_RECORD_ROW2_MACRO(SRAMwordsRB[j])-1] += 1; } // *** CLUSTER CODE *** if ((fillClusterHistograms == true) && (DATA_RECORD_TOT2_MACRO(SRAMwordsRB[j]) <= 13)) // Cluster hits only for Tot <= 13 { if (bcid_window_hit_array[DATA_RECORD_COLUMN2_MACRO(SRAMwordsRB[j])-1][DATA_RECORD_ROW2_MACRO(SRAMwordsRB[j])-1][(dh_counter-1)] == true) { if (!filename.empty()) fout << "ERROR: LOCATION CONFLICT" << endl; } bcid_window_tot_array[DATA_RECORD_COLUMN2_MACRO(SRAMwordsRB[j])-1][DATA_RECORD_ROW2_MACRO(SRAMwordsRB[j])-1][(dh_counter-1)] = DATA_RECORD_TOT2_MACRO(SRAMwordsRB[j]); bcid_window_hit_array[DATA_RECORD_COLUMN2_MACRO(SRAMwordsRB[j])-1][DATA_RECORD_ROW2_MACRO(SRAMwordsRB[j])-1][(dh_counter-1)] = true; } // *** CLUSTER CODE *** } } //} /*else // single hit { if (!filename.empty()) fout << endl; if (DATA_RECORD_TOT1_MACRO(SRAMwordsRB[j]) == 0xF) { if (!filename.empty()) fout << "ERROR: ToT(1) equal to 0xF" << endl; } if ((DATA_RECORD_COLUMN1_MACRO(SRAMwordsRB[j]) < 1) || (DATA_RECORD_COLUMN1_MACRO(SRAMwordsRB[j]) > 80)) { if (!filename.empty()) fout << "ERROR: COLUMN(1) OUT OF RANGE" << endl; } if ((DATA_RECORD_ROW1_MACRO(SRAMwordsRB[j]) < 1) || (DATA_RECORD_ROW1_MACRO(SRAMwordsRB[j]) > 336)) { if (!filename.empty()) fout << "ERROR: ROW(1) OUT OF RANGE" << endl; } if (valid_bcid_window == true) // Fill LV1ID-Histo (and only this one!) only if BCID window is valid { total_dr_counter += 1; if (DATA_RECORD_TOT1_MACRO(SRAMwordsRB[j]) <= 14) // We want to see all data the chip sends us. Users should mask this hits in their analysis if they want to. { total_hit_counter += 1; if (fillSourceScanHistograms == true) { HitLV1HistoFromRawData[(dh_counter-1)] += 1; //HitTOTHistoFromRawData[DATA_RECORD_COLUMN1_MACRO(SRAMwordsRB[j])-1][DATA_RECORD_ROW1_MACRO(SRAMwordsRB[j])-1][DATA_RECORD_TOT1_MACRO(SRAMwordsRB[j])] += 1; //HitHistoFromRawData[DATA_RECORD_COLUMN1_MACRO(SRAMwordsRB[j])-1][DATA_RECORD_ROW1_MACRO(SRAMwordsRB[j])-1] += 1; } // *** CLUSTER CODE *** if ((fillClusterHistograms == true) && (DATA_RECORD_TOT1_MACRO(SRAMwordsRB[j]) <= 13)) // Cluster hits only for Tot <= 13) { if (bcid_window_hit_array[DATA_RECORD_COLUMN1_MACRO(SRAMwordsRB[j])-1][DATA_RECORD_ROW1_MACRO(SRAMwordsRB[j])-1][(dh_counter-1)] == true) { if (!filename.empty()) fout << "ERROR: LOCATION CONFLICT" << endl; } bcid_window_tot_array[DATA_RECORD_COLUMN1_MACRO(SRAMwordsRB[j])-1][DATA_RECORD_ROW1_MACRO(SRAMwordsRB[j])-1][(dh_counter-1)] = DATA_RECORD_TOT1_MACRO(SRAMwordsRB[j]); bcid_window_hit_array[DATA_RECORD_COLUMN1_MACRO(SRAMwordsRB[j])-1][DATA_RECORD_ROW1_MACRO(SRAMwordsRB[j])-1][(dh_counter-1)] = true; } // *** CLUSTER CODE *** } } }*/ dr_counter++; } else if (EMPTY_RECORD_MACRO(SRAMwordsRB[j])) { if (!filename.empty()) fout << "0x" << std::setfill('0') << std::setw(6) << std::hex << SRAMwordsRB[j] << std::dec << std::setfill(' ') << endl; if (!filename.empty()) fout << "ER" << endl; if (!filename.empty()) fout << "WARNING: EMPTY RECORD" << endl; } else if (ADDRESS_RECORD_MACRO(SRAMwordsRB[j])) { if (!filename.empty()) fout << "0x" << std::setfill('0') << std::setw(6) << std::hex << SRAMwordsRB[j] << std::dec << std::setfill(' ') << endl; if (!filename.empty()) fout << "AR" << std::setw(2) << ADDRESS_RECORD_TYPE_MACRO(SRAMwordsRB[j]) << std::setw(6) << ADDRESS_RECORD_ADDRESS_MACRO(SRAMwordsRB[j]) << endl; } else if (VALUE_RECORD_MACRO(SRAMwordsRB[j])) { if (!filename.empty()) fout << "VR" << std::setfill('0') << std::setw(6) << std::hex << SRAMwordsRB[j] << std::dec << std::setfill(' ') << endl; if (!filename.empty()) fout << "VR" << /*std::setw(6)*/" " << VALUE_RECORD_VALUE_MACRO(SRAMwordsRB[j]) << endl; } else if (SERVICE_RECORD_MACRO(SRAMwordsRB[j])) { if (!filename.empty()) fout << "0x" << std::setfill('0') << std::setw(6) << std::hex << SRAMwordsRB[j] << std::dec << std::setfill(' ') << endl; if (!filename.empty()) fout << "SR" << /*std::setw(3)*/" " << SERVICE_RECORD_CODE_MACRO(SRAMwordsRB[j]) << /*std::setw(5)*/" " << SERVICE_RECORD_COUNTER_MACRO(SRAMwordsRB[j]) << endl; } else // unknown data word { if (!filename.empty()) fout << "0x" << std::setfill('0') << std::setw(6) << std::hex << SRAMwordsRB[j] << std::dec << std::setfill(' ') << endl; if (!filename.empty()) fout << "UNKNOWN" << endl; if (!filename.empty()) fout << "ERROR: UNKNOWN DATA WORD" << endl; } } // end loop // *** CLUSTER CODE *** if ((valid_bcid_window == true) && (fillClusterHistograms == true)) { Clustering(max_cluster_col_distance, max_cluster_row_distance, max_cluster_depth, timewalk_threshold_max, bcid_window_cluster_counter); // repeat this for every cluster in BCID windows and fill histograms for (int bcid_window_cluster_number = 1; bcid_window_cluster_number <= bcid_window_cluster_counter; bcid_window_cluster_number++) { cluster_size = 0; cluster_tot = 0; cluster_collision = 0; seed_col = 0; seed_row = 0; seed_eoe = 0; // preprocess cluster for (int current_eoe = 0; current_eoe < 16; current_eoe++) { for (int current_row = 0; current_row < 336; current_row++) { for (int current_col = 0; current_col < 80; current_col++) { // TOT & Size if (bcid_window_hit_cluster_number[current_col][current_row][current_eoe] == bcid_window_cluster_number) { cluster_size += 1; cluster_tot += bcid_window_tot_array[current_col][current_row][current_eoe]; } // collisions if (bcid_window_hit_collision_cluster_number[current_col][current_row][current_eoe] == bcid_window_cluster_number) { cluster_collision += 1; total_cluster_collision += 1; } // seed if (bcid_window_seed_cluster_number[current_col][current_row][current_eoe] == bcid_window_cluster_number) { seed_col = current_col; seed_row = current_row; seed_eoe = current_eoe; } } } } // sort out seeds/clusters that doesn't match rules //if ((seed_eoe == 0) || (seed_eoe >= (m_lengthLVL1 - max_cluster_depth)) || (bcid_window_cluster_counter != 1)) //{ // bcid_window_cluster_counter -= 1; // continue; //} // fill up all histograms // fill seed vs LV1 histo ClusterSeedLV1HistoFromRawData[seed_eoe][0] += 1; if ((cluster_size < 15) && (cluster_size >= 0)) { ClusterSeedLV1HistoFromRawData[seed_eoe][cluster_size] += 1; } else if (cluster_size >= 15) { ClusterSeedLV1HistoFromRawData[seed_eoe][15] += 1; } // fill seed occupancy histo ClusterSeedHistoFromRawData[seed_col][seed_row][0] += 1; if ((cluster_size < 15) && (cluster_size >= 0)) { ClusterSeedHistoFromRawData[seed_col][seed_row][cluster_size] += 1; } else if (cluster_size >= 15) { ClusterSeedHistoFromRawData[seed_col][seed_row][15] += 1; } // fill seed TOT histo ClusterSeedTOTHistoFromRawData/*[seed_col][seed_row]*/[(bcid_window_tot_array[seed_col][seed_row][seed_eoe])][0] += 1; if ((cluster_size < 15) && (cluster_size >= 0)) { ClusterSeedTOTHistoFromRawData/*[seed_col][seed_row]*/[(bcid_window_tot_array[seed_col][seed_row][seed_eoe])][cluster_size] += 1; } else if (cluster_size >= 15) { ClusterSeedTOTHistoFromRawData/*[seed_col][seed_row]*/[(bcid_window_tot_array[seed_col][seed_row][seed_eoe])][15] += 1; } // fill cluster size histogram if ((cluster_size < 15) && (cluster_size >= 0)) { ClusterSizeHistoFromRawData[cluster_size] += 1; } else if (cluster_size >= 15) { ClusterSizeHistoFromRawData[15] += 1; } // fill cluster TOT histograms depending on TOT and cluster size if ((cluster_tot < 15) && (cluster_tot >= 0)) { ClusterTOTHistoFromRawData[cluster_tot][0] += 1; if ((cluster_size < 15) && (cluster_size >= 0)) { ClusterTOTHistoFromRawData[cluster_tot][cluster_size] += 1; } else { ClusterTOTHistoFromRawData[cluster_tot][15] += 1; } } else if (cluster_tot >= 15) { ClusterTOTHistoFromRawData[15][0] += 1; if ((cluster_size < 15) && (cluster_size >= 0)) { ClusterTOTHistoFromRawData[15][cluster_size] += 1; } else { ClusterTOTHistoFromRawData[15][15] += 1; } } } // fill seed per trigger array if ((bcid_window_cluster_counter < 15) && (bcid_window_cluster_counter >= 0)) { ClusterSeedPerTriggerHistoFromRawData[bcid_window_cluster_counter] += 1; } else if (bcid_window_cluster_counter >= 15) { ClusterSeedPerTriggerHistoFromRawData[15] += 1; } // debug: write selected BCID windows //ofstream fout; //fout.open("./debug_cluster.raw", ios::app); // append data //if (!fout.is_open()) // fails to open file // return; ////fout.setf(ios_base::showbase); // show 0x prefix for hex //if (/*(cluster_size >= 6) && (bcid_window_cluster_counter == 1)*//*(cluster_tot == 13) && *//*(total_cluster_collision != 0) && */(bcid_window_cluster_counter >= 3)/*(cluster_tot >= 11) && (cluster_tot <= 14)*/) //{ // fout << "Raw data: 0x" << std::setfill('0') << std::setw(8) << std::hex << SRAMwordsRB[bcid_window_end] << std::dec << std::setfill(' ') << endl; // trigger word, TurboDAQ specific // // loop through BCID window // for (int j = bcid_window_start; j < bcid_window_end; j++) // { // fout << "Raw data: 0x" << std::setfill('0') << std::setw(8) << std::hex << (SRAMwordsRB[j] << 7) << std::dec << std::setfill(' ') << endl; // if ((HEADER_MACRO(SRAMwordsRB[j]) == 1) && ((FLAG_MACRO(SRAMwordsRB[j]) & FLAG_WO_STATUS) == FLAG_WO_STATUS)) // EOE word // { // fout << BCID_3_0_MACRO(SRAMwordsRB[j]) << " " << L1ID_MACRO(SRAMwordsRB[j]) << " " << FLAG_MACRO(SRAMwordsRB[j]) << " " << "0 0" << " " << BCID_MACRO(SRAMwordsRB[j]) << endl; // TurboDAQ specific, TODO: Scanparameter // // check for ERROR // if (FLAG_MACRO(SRAMwordsRB[j]) != FLAG_NO_ERROR) // { // if ((FLAG_MACRO(SRAMwordsRB[j]) & FLAG_ERROR_1) == FLAG_ERROR_1) fout << "ERROR: ERROR 1" << endl; // ERROR 1, EOC Buffer Overflow // if ((FLAG_MACRO(SRAMwordsRB[j]) & FLAG_ERROR_2) == FLAG_ERROR_2) fout << "ERROR: ERROR 2" << endl; // ERROR 2, Hamming Code Error // if ((FLAG_MACRO(SRAMwordsRB[j]) & FLAG_ERROR_3) == FLAG_ERROR_3) fout << "ERROR: ERROR 3" << endl; // ERROR 3, Command/Global Register Parity Error // if ((FLAG_MACRO(SRAMwordsRB[j]) & FLAG_ERROR_4) == FLAG_ERROR_4) fout << "ERROR: ERROR 4" << endl; // ERROR 4, HitParity Error // } // // check for WARNING // if (WARN_MACRO(SRAMwordsRB[j]) != 0) // { // fout << "ERROR: WARNING" << endl; // WARNING, Bit Flip Error // } // eoe_counter_debug++; // } // else if ((HEADER_MACRO(SRAMwordsRB[j]) == 1) && (ROW_MACRO(SRAMwordsRB[j]) < 160) && (COL_MACRO(SRAMwordsRB[j]) < 18)) // hit word // { // fout << BCID_3_0_MACRO(SRAMwordsRB[j]) << " " << COL_MACRO(SRAMwordsRB[j]) << " " << ROW_MACRO(SRAMwordsRB[j]) << " " << "0 0" << " " << TOT_MACRO(SRAMwordsRB[j]) << endl; // TurboDAQ specific, TODO: Scanparameter // fout << "Hit: " << bcid_window_hit_cluster_number[COL_MACRO(SRAMwordsRB[j])][ROW_MACRO(SRAMwordsRB[j])][eoe_counter_debug] << "\tSeed: " << bcid_window_seed_cluster_number[COL_MACRO(SRAMwordsRB[j])][ROW_MACRO(SRAMwordsRB[j])][eoe_counter_debug] << "\tCollision: " << bcid_window_hit_collision_cluster_number[COL_MACRO(SRAMwordsRB[j])][ROW_MACRO(SRAMwordsRB[j])][eoe_counter_debug] << endl; // } // else // no EOE word, no hit word // { // fout << "ERROR: UNKNOWN WORD" << endl; // } // } //} //// close file //fout.close(); } // *** CLUSTER CODE *** valid_lv1id = true; valid_bcid = true; valid_data = true; valid_trigger_number = true; bcid_window_dh_counter = 0; bcid_window_dr_counter = 0; dh_counter = 0; dr_counter = 0; // SRAMwordsRB[i+1] is also trigger data bcid_window_start = i + 2; i++; } else if (EMPTY_RECORD_MACRO(SRAMwordsRB[i]) || ADDRESS_RECORD_MACRO(SRAMwordsRB[i]) || VALUE_RECORD_MACRO(SRAMwordsRB[i]) || SERVICE_RECORD_MACRO(SRAMwordsRB[i])) // other records { ; // do nothing here } else { valid_data = false; } } if (close_file == true) { if (!filename.empty()) fout << "End of dfifo block read" << endl << "#"; // last line of the output file, TurboDAQ specific } if (close_file == true && !filename.empty()) { // measure processing time #ifdef __VISUALC__ stop = GetTickCount(); total_processing_time += (stop - start); #endif #ifdef CF__LINUX gettimeofday(&stop, 0); total_processing_time += (((stop.tv_sec - start.tv_sec) * 1000) + int (((stop.tv_usec - start.tv_usec) / 1000))); #endif int digits = 0; if (digits < (int)log10((float)total_trigger_counter)) digits = (int)log10((float)total_trigger_counter); if (digits < (int)log10((float)total_valid_bcid_window)) digits = (int)log10((float)total_valid_bcid_window); if (digits < (int)log10((float)total_no_dr_counter)) digits = (int)log10((float)total_no_dr_counter); if (digits < (int)log10((float)total_dh_counter)) digits = (int)log10((float)total_dh_counter); if (digits < (int)log10((float)total_dr_counter)) digits = (int)log10((float)total_dr_counter); if (digits < (int)log10((float)total_hit_counter)) digits = (int)log10((float)total_hit_counter); fout << endl << "# " << "Triggers:" << endl << "# "; fout.flags(std::ios::right); fout.width(digits+1); fout << total_trigger_counter; fout << endl << "# " << "Valid BCID Windows:" << endl << "# "; fout.flags(std::ios::right); fout.width(digits+1); fout << total_valid_bcid_window; fout << endl << "# " << "Valid BCID Windows w/o Data Records:" << endl << "# "; fout.flags(std::ios::right); fout.width(digits+1); fout << total_no_dr_counter; fout << endl << "# " << "Valid Data Headers:" << endl << "# "; fout.flags(std::ios::right); fout.width(digits+1); fout << total_dh_counter; fout << endl << "# " << "Valid Data Records:" << endl << "# "; fout.flags(std::ios::right); fout.width(digits+1); fout << total_dr_counter; fout << endl << "# " << "Valid Hits:" << endl << "# "; fout.flags(std::ios::right); fout.width(digits+1); fout << total_hit_counter; fout << endl << "#"; if (fillSourceScanHistograms == true) { fout << endl << "# LVL1 Histogram:"; digits = 0; for (int i = 0; i < m_lengthLVL1; i++) { if (digits < (int)log10((float)HitLV1HistoFromRawData[i])) digits = (int)log10((float)HitLV1HistoFromRawData[i]); } for (int i = 0; i < m_lengthLVL1; i++) { fout << endl << "# "; fout.flags(std::ios::right); fout.width(2); fout << i+1; fout <<": "; fout.flags(std::ios::right); fout.width(digits+1); fout << HitLV1HistoFromRawData[i]; fout << " Hits"; } } fout << endl << "#"; fout << endl << "# " << "Processing Time: " << (total_processing_time) << " ms" << endl << "#"; //time_t stop_time; time(&stop_time); char timebuf[26]; #ifdef __VISUALC__ ctime_s(timebuf, 26, &stop_time); #else // CF__LINUX ctime_r(&stop_time, timebuf); #endif // __VISUALC__ fout << endl << "# " << string(timebuf) << "#"; } // close file if (!filename.empty()) fout.close(); FillHistosFromRawData(); return true; } void ConfigRegister::ClearHitTOTHistoFromRawData() { for (int col = 0; col < 80; col++) { for (int row = 0; row < 336; row++) { for (int TOT = 0; TOT < 16; TOT++) { HitTOTHistoFromRawData[col][row][TOT] = 0; } } } } void ConfigRegister::ClearHitHistoFromRawData() { for (int col = 0; col < 80; col++) { for (int row = 0; row < 336; row++) { HitHistoFromRawData[col][row] = 0; } } } void ConfigRegister::ClearHitLV1HistoFromRawData() { for (int LV1 = 0; LV1 < 16; LV1++) { HitLV1HistoFromRawData[LV1] = 0; } } void ConfigRegister::ClearClusterSizeHistoFromRawData() { for (int Size = 0; Size < 16; Size++) { ClusterSizeHistoFromRawData[Size] = 0; } } void ConfigRegister::ClearClusterTOTHistoFromRawData() { for (int TOT = 0; TOT < 16; TOT++) { for (int Size = 0; Size < 16; Size++) { ClusterTOTHistoFromRawData[TOT][Size] = 0; } } } void ConfigRegister::ClearClusterSeedTOTHistoFromRawData() { //for (int col = 0; col < 80; col++) //{ // for (int row = 0; row < 336; row++) // { for (int TOT = 0; TOT < 16; TOT++) { for (int Size = 0; Size < 16; Size++) { ClusterSeedTOTHistoFromRawData/*[col][row]*/[TOT][Size] = 0; } } // } //} } void ConfigRegister::ClearClusterSeedLV1HistoFromRawData() { for (int LV1 = 0; LV1 < 16; LV1++) { for (int Size = 0; Size < 16; Size++) { ClusterSeedLV1HistoFromRawData[LV1][Size] = 0; } } } void ConfigRegister::ClearClusterSeedHistoFromRawData() { for (int col = 0; col < 80; col++) { for (int row = 0; row < 336; row++) { for (int Size = 0; Size < 16; Size++) { ClusterSeedHistoFromRawData[col][row][Size] = 0; } } } } void ConfigRegister::ClearClusterSeedPerTriggerHistoFromRawData() { for (int Amount = 0; Amount < 16; Amount++) { ClusterSeedPerTriggerHistoFromRawData[Amount] = 0; } } void ConfigRegister::Clustering(int max_cluster_col_distance, int max_cluster_row_distance, int max_cluster_depth, int timewalk_threshold_max, int& bcid_window_cluster_counter) { int seed_col = 0; int seed_row = 0; for (int current_eoe = 0; current_eoe < 16; current_eoe++) { while (FindNextSeed(seed_col, seed_row, current_eoe, max_cluster_depth) == true) { bcid_window_cluster_counter += 1; bcid_window_seed_cluster_number[seed_col][seed_row][current_eoe] = bcid_window_cluster_counter; AdvancedClustering(seed_col, seed_row, current_eoe, current_eoe, max_cluster_col_distance, max_cluster_row_distance, max_cluster_depth, timewalk_threshold_max, bcid_window_cluster_counter); } } } bool ConfigRegister::FindNextSeed(int& seed_col, int& seed_row, int eoe, int max_cluster_depth, int col_start, int col_end, int row_start, int row_end) { for (int current_col = col_start; current_col <= col_end; current_col++) { for (int current_row = row_start; current_row <= row_end; current_row++) { if ((bcid_window_hit_array[current_col][current_row][eoe] == true) && (bcid_window_hit_cluster_number[current_col][current_row][eoe] == 0)) { if (HitIsSeed(current_col, current_row, eoe, max_cluster_depth, col_start, col_end, row_start, row_end) == true) { seed_col = current_col; seed_row = current_row; return true; } } } } return false; } bool ConfigRegister::HitIsSeed(int seed_col, int seed_row, int seed_eoe, int max_cluster_depth, int col_start, int col_end, int row_start, int row_end) { int cluster_size, cluster_tot, current_cluster_size, current_cluster_tot; cluster_size = 0; cluster_tot = 0; for (int eoe = 0; eoe < 16; eoe++) { for (int row = 0; row < 336; row++) { for (int col = 0; col < 80; col++) { seed_neighbours_hit_processed_array[col][row][eoe] = false; } } } SeedNeighbours(seed_col, seed_row, seed_eoe, seed_eoe, max_cluster_depth, cluster_size, cluster_tot); for (int current_col = col_start; current_col <= col_end; current_col++) { for (int current_row = row_start; current_row <= row_end; current_row++) { if (((current_col != seed_col) || (current_row != seed_row)) && (bcid_window_hit_array[current_col][current_row][seed_eoe] == true) && (bcid_window_hit_cluster_number[current_col][current_row][seed_eoe] == 0)) { current_cluster_size = 0; current_cluster_tot = 0; for (int eoe = 0; eoe < 16; eoe++) { for (int row = 0; row < 336; row++) { for (int col = 0; col < 80; col++) { seed_neighbours_hit_processed_array[col][row][eoe] = false; } } } SeedNeighbours(current_col, current_row, seed_eoe, seed_eoe, max_cluster_depth, current_cluster_size, current_cluster_tot); if (current_cluster_size > cluster_size) { return false; } else if (current_cluster_size == cluster_size) { if (current_cluster_tot > cluster_tot) { return false; } else if (current_cluster_tot == cluster_tot) { if ((bcid_window_tot_array[current_col][current_row][seed_eoe] > bcid_window_tot_array[seed_col][seed_row][seed_eoe])) { return false; } } } } } } return true; } bool ConfigRegister::Collision(int eoe, int bcid_window_cluster_number) { bool collision = false; for (int current_row = 0; current_row < 336; current_row++) { for (int current_col = 0; current_col < 80; current_col++) { if (bcid_window_hit_array[current_col][current_row][eoe] == true) { for (int current_eoe = 0; (current_eoe < eoe) && (current_eoe < 16); current_eoe++) { if (bcid_window_hit_cluster_number[current_col][current_row][current_eoe] == bcid_window_cluster_number) { bcid_window_hit_collision_cluster_number[current_col][current_row][eoe] = bcid_window_cluster_number; collision = true; } } } } } return collision; } void ConfigRegister::AdvancedClustering(int seed_col, int seed_row, int seed_eoe, int eoe_start, int max_cluster_col_distance, int max_cluster_row_distance, int max_cluster_depth, int timewalk_threshold_max, int bcid_window_cluster_number) { int col_start, col_end, row_start, row_end, eoe_end; if ((bcid_window_hit_array[seed_col][seed_row][seed_eoe] == true) && (bcid_window_hit_cluster_number[seed_col][seed_row][seed_eoe] == 0) && ((bcid_window_tot_array[seed_col][seed_row][seed_eoe] <= timewalk_threshold_max) || (seed_eoe == eoe_start))) { bcid_window_hit_cluster_number[seed_col][seed_row][seed_eoe] = bcid_window_cluster_number; if ((seed_col - max_cluster_col_distance) < 0) { col_start = 0; } else { col_start = seed_col - max_cluster_col_distance; } if ((seed_col + max_cluster_col_distance) > 79) { col_end = 17; } else { col_end = seed_col + max_cluster_col_distance; } if ((seed_row - max_cluster_row_distance) < 0) { row_start = 0; } else { row_start = seed_row - max_cluster_row_distance; } if ((seed_row + max_cluster_row_distance) > 335) { row_end = 159; } else { row_end = seed_row + max_cluster_row_distance; } if ((eoe_start + max_cluster_depth) > 15) { eoe_end = 15; } else { eoe_end = eoe_start + max_cluster_depth; } for (int current_eoe = eoe_start; current_eoe <= eoe_end; current_eoe++) { //Collision(current_eoe, bcid_window_cluster_number); for (int current_row = row_start; current_row <= row_end; current_row++) { for (int current_col = col_start; current_col <= col_end; current_col++) { AdvancedClustering(current_col, current_row, current_eoe, eoe_start, max_cluster_col_distance, max_cluster_row_distance, max_cluster_depth, timewalk_threshold_max, bcid_window_cluster_number); } } } } } void ConfigRegister::SeedNeighbours(int seed_col, int seed_row, int seed_eoe, int eoe_start, int max_cluster_depth, int& cluster_size, int& cluster_tot) { if ((bcid_window_hit_array[seed_col][seed_row][seed_eoe] == true) && (seed_neighbours_hit_processed_array[seed_col][seed_row][seed_eoe] == false)) { seed_neighbours_hit_processed_array[seed_col][seed_row][seed_eoe] = true; for (int current_eoe = eoe_start; (current_eoe <= (eoe_start + max_cluster_depth)) && (current_eoe < 16); current_eoe++) { // search clockwise for hits if ((seed_col + 1) < 80) { SeedNeighbours((seed_col + 1), seed_row, current_eoe, eoe_start, max_cluster_depth, cluster_size, cluster_tot); } if (((seed_col + 1) < 80) && ((seed_row - 1) >= 0)) { SeedNeighbours((seed_col + 1), (seed_row - 1), current_eoe, eoe_start, max_cluster_depth, cluster_size, cluster_tot); } if ((seed_row - 1) >= 0) { SeedNeighbours(seed_col, (seed_row - 1), current_eoe, eoe_start, max_cluster_depth, cluster_size, cluster_tot); } if (((seed_col - 1) >= 0) && ((seed_row - 1) >= 0)) { SeedNeighbours((seed_col - 1), (seed_row - 1), current_eoe, eoe_start, max_cluster_depth, cluster_size, cluster_tot); } if ((seed_col - 1) >= 0) { SeedNeighbours((seed_col - 1), seed_row, current_eoe, eoe_start, max_cluster_depth, cluster_size, cluster_tot); } if (((seed_col - 1) >= 0) && ((seed_row + 1) < 336)) { SeedNeighbours((seed_col - 1), (seed_row + 1), current_eoe, eoe_start, max_cluster_depth, cluster_size, cluster_tot); } if ((seed_row + 1) < 336) { SeedNeighbours(seed_col, (seed_row + 1), current_eoe, eoe_start, max_cluster_depth, cluster_size, cluster_tot); } if (((seed_col + 1) < 80) && ((seed_row + 1) < 336)) { SeedNeighbours((seed_col + 1), (seed_row + 1), current_eoe, eoe_start, max_cluster_depth, cluster_size, cluster_tot); } } } } void ConfigRegister::GetConfHisto(int col, int row, int confStep, int &Value) { if ((col < 80) && (col >= 0) && (row < 336) && (row >= 0) && (confStep < 1024) && (confStep >= 0)) Value = ConfHisto[col][row][confStep]; else Value = -1; } void ConfigRegister::ClearConfHisto() { for (int col = 0; col < 80; col++) { for (int row = 0; row < 336; row++) { for (int confStep = 0; confStep < 1024; confStep++) { ConfHisto[col][row][confStep] = 0; } } } } void ConfigRegister::MakeConfHisto(int confStep) { int startIndex = confStep - (confStep%32); for (int col = 0; col < 80; col++) { for (int row = 0; row < 336; row++) { for (int index = 0; (index < 32) && ((startIndex + index) < 1024) && (index <= (confStep%32)); index++) { ConfHisto[col][row][(startIndex + index)] += SRAMdataRB[((index << 16) | ((row+1) << 7) | (col+1))]; } } } } void ConfigRegister::GetTOTHisto(int col, int row, int tot, int &Value) { if ((col < 80) && (col >= 0) && (row < 336) && (row >= 0) && (tot < 16) && (tot >= 0)) Value = TOTHisto[col][row][tot]; else Value = -1; } void ConfigRegister::ClearTOTHisto() { for (int col = 0; col < 80; col++) { for (int row = 0; row < 336; row++) { for (int tot = 0; tot < 16; tot++) { TOTHisto[col][row][tot] = 0; } } } } void ConfigRegister::MakeTOTHisto() { int index; for (int col = 0; col < 80; col++) { for (int row = 0; row < 336; row++) { for (int tot = 0; tot < 16; tot++) { index = ((tot << 16) | ((row+1) << 7) | (col+1)); TOTHisto[col][row][tot] = SRAMdataRB[index]; } } } } void ConfigRegister::GetHitTOTHistoFromRawData(int col, int row, int TOT, int& Value) // ToT code histogram, run mode { if ((col < 80) && (col >= 0) && (row < 336) && (row >= 0) && (TOT < 16) && (TOT >= 0)) Value = HitTOTHistoFromRawData[col][row][TOT]; // TOT = 0 exists -> ToT code else Value = -1; } void ConfigRegister::GetHitHistoFromRawData(int col, int row, int& Value) // hit map, run mode { if ((col < 80) && (col >= 0) && (row < 336) && (row >= 0)) Value = HitHistoFromRawData[col][row]; else Value = -1; } void ConfigRegister::GetHitLV1HistoFromRawData(int LV1ID, int& Value) // LV1 histogram, run mode { if ((LV1ID < 16) && (LV1ID >= 0)) Value = HitLV1HistoFromRawData[LV1ID]; else Value = -1; } void ConfigRegister::GetClusterSizeHistoFromRawData(int Size, int& Value) { if ((Size < 16) && (Size >= 0)) Value = ClusterSizeHistoFromRawData[Size]; else Value = -1; } void ConfigRegister::GetClusterTOTHistoFromRawData(int TOT, int Size, int& Value) { if ((TOT < 16) && (TOT >= 0) && (Size < 16) && (Size >= 0)) Value = ClusterTOTHistoFromRawData[TOT][Size]; // TOT = 0 exists!!! else Value = -1; } void ConfigRegister::GetClusterSeedTOTHistoFromRawData(/*int col, int row, */int TOT, int Size, int& Value) { if (/*(col < 80) && (col >= 0) && (row < 336) && (row >= 0) && */(TOT < 16) && (TOT >= 0) && (Size < 16) && (Size >= 0)) Value = ClusterSeedTOTHistoFromRawData/*[col][row]*/[TOT][Size]; // TOT = 0 exists!!! else Value = -1; } void ConfigRegister::GetClusterSeedLV1HistoFromRawData(int LV1ID, int Size, int& Value) { if ((LV1ID < 16) && (LV1ID >= 0) && (Size < 16) && (Size >= 0)) Value = ClusterSeedLV1HistoFromRawData[LV1ID][Size]; else Value = -1; } void ConfigRegister::GetClusterSeedHistoFromRawData(int col, int row, int Size, int& Value) { if ((col < 80) && (col >= 0) && (row < 336) && (row >= 0) && (Size < 16) && (Size >= 0)) Value = ClusterSeedHistoFromRawData[col][row][Size]; else Value = -1; } void ConfigRegister::GetClusterSeedPerTriggerHistoFromRawData(int Amount, int& Value) { if ((Amount < 16) && (Amount >= 0)) Value = ClusterSeedPerTriggerHistoFromRawData[Amount]; else Value = -1; } void ConfigRegister::BuildWords() { for(int i = 0, byte = 0; i < SRAM_WORDSIZE; i++, byte += WORDSIZE) { if (i == 0) cout << "Beginning to build words..." << endl; SRAMwordsRB[i] = (0x00 << 24) | (((unsigned int)SRAMdataRB[byte + 2]) << 16) | (((unsigned int)SRAMdataRB[byte + 1]) << 8) | (unsigned int)SRAMdataRB[byte]; } } // writing SRAM words (24-bit) bool ConfigRegister::WriteSRAMWords(char *filename) { // open file, ios::app: append data, ios::out: overwrite existing file ofstream fout(filename, ios::app); if (!fout.is_open()) // fails to open file return false; // create timestamp time_t ltime; time(<ime); char timebuf[26]; #ifdef __VISUALC__ ctime_s(timebuf, 26, <ime); #else // CF__LINUX ctime_r(<ime, timebuf); #endif // __VISUALC__ fout << endl << string(timebuf) << endl; // data processing //fout.setf(ios_base::showbase); // show 0x prefix for hex if ((!isCalMode) && (!isTOTMode)) // run mode { fout << "Run mode." << endl; } else if (isCalMode && (!isTOTMode)) // cal mode { fout << "Calibration mode." << endl; } else if (isTOTMode && (!isCalMode)) // TOT mode { fout << "TOT mode." << endl; } else { fout << "Unknown mode." << endl; } for (int i = 0; i < (SRAM_WORDSIZE); i++) { fout.flags(std::ios::right); fout.width(6); fout << i; fout << ": "; fout.flags(std::ios::right); fout << "0x" << std::setfill('0') << std::setw(6) << std::hex << SRAMwordsRB[i] << std::dec << std::setfill(' ') << endl; } fout.close(); return true; } // writing SRAM bits from words bool ConfigRegister::WriteSRAMBitsFromWords(char *filename) { // open file, ios::app: append data, ios::out: overwrite existing file ofstream fout(filename, ios::app); if (!fout.is_open()) // fails to open file return false; // create timestamp time_t ltime; time(<ime); char timebuf[26]; #ifdef __VISUALC__ ctime_s(timebuf, 26, <ime); #else // CF__LINUX ctime_r(<ime, timebuf); #endif // __VISUALC__ fout << endl << string(timebuf) << endl; // data processing //fout.setf(ios_base::showbase); // show 0x prefix for hex if ((!isCalMode) && (!isTOTMode)) // run mode { fout << "Run mode." << endl; } else if (isCalMode && (!isTOTMode)) // cal mode { fout << "Calibration mode." << endl; } else if (isTOTMode && (!isCalMode)) // TOT mode { fout << "TOT mode." << endl; } else { fout << "Unknown mode." << endl; } int shift = (WORDSIZE * 8) - 1; unsigned int mask; for (int i = 0; i < (SRAM_WORDSIZE); i++) { mask = 1 << shift; fout.flags(std::ios::right); fout.width(6); fout << i; fout << ":"; for (int j = 0; j <= shift; j++) { if ((j%8) == 0) fout << " "; fout << ((SRAMwordsRB[i] & mask) ? "1" : "0"); mask = (mask >> 1); } fout << endl; } fout.close(); return true; } // writing SRAM bytes (8-bit) bool ConfigRegister::WriteSRAMBytes(char *filename) { // open file, ios::app: append data, ios::out: overwrite existing file ofstream fout(filename, ios::app); if (!fout.is_open()) // fails to open file return false; // create timestamp time_t ltime; time(<ime); char timebuf[26]; #ifdef __VISUALC__ ctime_s(timebuf, 26, <ime); #else // CF__LINUX ctime_r(<ime, timebuf); #endif // __VISUALC__ fout << endl << string(timebuf) << endl; // data processing //fout.setf(ios_base::showbase); // show 0x prefix for hex if ((!isCalMode) && (!isTOTMode)) // run mode { fout << "Run mode." << endl; } else if (isCalMode && (!isTOTMode)) // cal mode { fout << "Calibration mode." << endl; } else if (isTOTMode && (!isCalMode)) // TOT mode { fout << "TOT mode." << endl; } else { fout << "Unknown mode." << endl; } for (int i = 0; i < (SRAM_BYTESIZE); i++) { fout.flags(std::ios::right); fout.width(7); fout << i; fout << ": "; fout.flags(std::ios::right); fout << "0x" << std::setfill('0') << std::setw(2) << std::hex << ((unsigned int)SRAMdataRB[i]) << std::setfill(' ') << std::dec << endl; } fout.close(); return true; } // writing SRAM bits from bytes bool ConfigRegister::WriteSRAMBitsFromBytes(char *filename) { // open file, ios::app: append data, ios::out: overwrite existing file ofstream fout(filename, ios::app); if (!fout.is_open()) // fails to open file return false; // create timestamp time_t ltime; time(<ime); char timebuf[26]; #ifdef __VISUALC__ ctime_s(timebuf, 26, <ime); #else // CF__LINUX ctime_r(<ime, timebuf); #endif // __VISUALC__ fout << endl << string(timebuf) << endl; // data processing //fout.setf(ios_base::showbase); // show 0x prefix for hex if ((!isCalMode) && (!isTOTMode)) // run mode { fout << "Run mode." << endl; } else if (isCalMode && (!isTOTMode)) // cal mode { fout << "Calibration mode." << endl; } else if (isTOTMode && (!isCalMode)) // TOT mode { fout << "TOT mode." << endl; } else { fout << "Unknown mode." << endl; } int shift = (WORDSIZE * 8) - 1; unsigned char mask; unsigned char SRAMdataRB_tmp; int byte; for (int i = 0; i < SRAM_BYTESIZE; i++) { if ((i%WORDSIZE) == 0) { fout.flags(std::ios::right); fout.width(6); fout << (i/WORDSIZE); fout << ":"; } fout << " "; byte = WORDSIZE * int(i/WORDSIZE) + 3 - (i%WORDSIZE); // reverse order if (byte < (SRAM_BYTESIZE - (SRAM_BYTESIZE%WORDSIZE))) SRAMdataRB_tmp = SRAMdataRB[byte]; else SRAMdataRB_tmp = SRAMdataRB[i]; mask = (1 << shift); for (int j = 0; j <= shift; j++) { fout << ((SRAMdataRB_tmp & mask) ? "1" : "0"); mask = (mask >> 1); } if (((i+1)%WORDSIZE) == 0) fout << endl; } fout.close(); return true; } // old raw data format bool ConfigRegister::FileSaveRB(const char *filename, int event_quant, bool attach_data) { ofstream fout; time_t ltime; char timebuf[26]; time(<ime); #ifndef CF__LINUX ctime_s(timebuf, 26, <ime); #else ctime_r(<ime, timebuf); #endif if (attach_data) fout.open(filename, ofstream::app); else fout.open(filename); if (fout == NULL) return false; if (!attach_data) { fout << "#" << endl; fout << "#" << endl; fout << "# last change: " << std::string(timebuf) << endl; fout << "#" << endl; fout << "#" << endl; fout << endl; } for (int word = 0; (word < event_quant) && (word < (SRAM_WORDSIZE-1)); word++) { if (!EMPTY_RECORD_MACRO(SRAMwordsRB[word])) // no empty record { if (TRIGGER_WORD_MACRO(SRAMwordsRB[word])) // trigger word { fout << "0x" << std::setfill('0') << std::setw(6) << std::hex << SRAMwordsRB[word] << std::dec << std::setfill(' ') << endl; fout << "0x" << std::setfill('0') << std::setw(6) << std::hex << SRAMwordsRB[word+1] << std::dec << std::setfill(' ') << endl; fout << "TRIGGER_ID = " << TRIGGER_NUMBER_MACRO2(SRAMwordsRB[word], SRAMwordsRB[word+1]); fout << endl; fout << endl; fout << endl; fout << "# ---------- new trigger window -------------" << endl; word++; // SRAMwordsRB[word+1] also contains trigger data } else { fout.flags(std::ios::right); fout << "0x" << std::setfill('0') << std::setw(6) << std::hex << SRAMwordsRB[word] << std::dec << std::setfill(' ') << endl; if ((SRAMwordsRB[word] & 0xff000000) != 0) fout << "\t !!! error: byte 3 not 0"; if (DATA_HEADER_MACRO(SRAMwordsRB[word])) if (FEI4B) fout << "\t\t word: " << std::dec << word << "\t Data Header\t LV1ID \t" << DATA_HEADER_LV1ID_MACRO(SRAMwordsRB[word]) << "\t BCID \t" << DATA_HEADER_BCID_MACRO(SRAMwordsRB[word]); else fout << "\t\t word: " << std::dec << word << "\t Data Header\t LV1ID \t" << DATA_HEADER_LV1ID_MACRO_FEI4B(SRAMwordsRB[word]) << "\t BCID \t" << DATA_HEADER_BCID_MACRO_FEI4B(SRAMwordsRB[word]); if (SERVICE_RECORD_MACRO(SRAMwordsRB[word])) { fout << "\t\t word: " << std::dec << word << "\t Service Record\t Code \t" << SERVICE_RECORD_CODE_MACRO(SRAMwordsRB[word]) << "\t Counter \t" << SERVICE_RECORD_COUNTER_MACRO(SRAMwordsRB[word]); } else if (DATA_RECORD_MACRO(SRAMwordsRB[word])) { fout << "\t\t word: " << std::dec << word << "\t col \t" << DATA_RECORD_COLUMN1_MACRO(SRAMwordsRB[word]) << "\t row \t" << DATA_RECORD_ROW1_MACRO(SRAMwordsRB[word]) << "\t tot0 \t" << DATA_RECORD_TOT1_MACRO(SRAMwordsRB[word]) << "\t tot1 \t" << DATA_RECORD_TOT2_MACRO(SRAMwordsRB[word]); } else fout << "\t\t word: " << std::dec << word; fout << endl; } } } fout.close(); return true; } bool ConfigRegister::CheckDataConsisty(const char * filename, bool attach_data, bool write_summary) { ofstream fout; time_t ltime; char timebuf[26]; time(<ime); #ifndef CF__LINUX ctime_s(timebuf, 26, <ime); #else ctime_r(<ime, timebuf); #endif if (attach_data) fout.open(filename, ofstream::app); else fout.open(filename); if (fout == NULL) return false; if (!attach_data) { fout << "#" << endl; fout << "#" << endl; fout << "# last change: " << std::string(timebuf) << endl; fout << "#" << endl; fout << "#" << endl; fout << endl; nr_SR_detected = 0; nr_DH_inconsistent = 0; nr_DR_wo_DH = 0; nr_lv1_jumps = 0; nr_bcid_jumps = 0; } int lv1 = 0; int nr_dr = 0; int nr_sr = 0; int nr_dh = ReadRegister(CS_L_LV1); int windowsize = 0; //int currentword = 0; int lv1id = 0; int first_trigger_window = true; int bcid = 0; bool error_detected = false; for (int word = 0; word < SRAM_WORDSIZE; word++) { windowsize++; // search for trigger number if (TRIGGER_WORD_MACRO(SRAMwordsRB[word])) { int data = SRAMwordsRB[word]; //int trigger_id = TRIGGER_NUMBER_MACRO2(SRAMwordsRB[word], SRAMwordsRB[word+1]); //for (int i = 0; i < windowsize; i++) for (int i = windowsize-1; i >= 0; i--) { if (DATA_HEADER_MACRO(SRAMwordsRB[word - i])) { lv1 = lv1 + 1; // check for lv1 jumps if (first_trigger_window && (lv1 == 1)) if (!FEI4B) lv1id = DATA_HEADER_LV1ID_MACRO(SRAMwordsRB[word - i]); else lv1id = DATA_HEADER_LV1ID_MACRO_FEI4B(SRAMwordsRB[word - i]); else if (lv1id == 128) lv1id = 0; else { if (!FEI4B) { if (DATA_HEADER_LV1ID_MACRO(SRAMwordsRB[word - i]) != lv1id) { error_detected = true; fout << "LV1ID jump in TRIGGER_ID = " << TRIGGER_NUMBER_MACRO2(SRAMwordsRB[word], SRAMwordsRB[word+1]) << endl; nr_lv1_jumps++; } } else { if (DATA_HEADER_LV1ID_MACRO_FEI4B(SRAMwordsRB[word - i]) != lv1id) { error_detected = true; fout << "LV1ID jump in TRIGGER_ID = " << TRIGGER_NUMBER_MACRO2(SRAMwordsRB[word], SRAMwordsRB[word+1]) << endl; nr_lv1_jumps++; } } } // check for bcid jumps if (lv1 == 1) { if (!FEI4B) bcid = DATA_HEADER_BCID_MACRO(SRAMwordsRB[word - i]); else bcid = DATA_HEADER_BCID_MACRO_FEI4B(SRAMwordsRB[word - i]); } else { bcid++; if (bcid == 256) bcid = 0; if (!FEI4B) { if (bcid != DATA_HEADER_BCID_MACRO(SRAMwordsRB[word - i])) { error_detected = true; fout << "BCID jump in TRIGGER_ID = " << TRIGGER_NUMBER_MACRO2(SRAMwordsRB[word], SRAMwordsRB[word+1]) << endl; nr_bcid_jumps++; } } else { if (bcid != DATA_HEADER_BCID_MACRO_FEI4B(SRAMwordsRB[word - i])) { error_detected = true; fout << "BCID jump in TRIGGER_ID = " << TRIGGER_NUMBER_MACRO2(SRAMwordsRB[word], SRAMwordsRB[word+1]) << endl; nr_bcid_jumps++; } } } } if (DATA_RECORD_MACRO(SRAMwordsRB[word - i])) { data = SRAMwordsRB[word - i]; // count # dr nr_dr++; // check for DR before DH if (lv1 == 0) { error_detected = true; fout << "Hitword before first DH in TRIGGER_ID = " << TRIGGER_NUMBER_MACRO2(SRAMwordsRB[word], SRAMwordsRB[word+1]) << endl; nr_DR_wo_DH++; } } first_trigger_window = false; } if (error_detected) { for (int i = windowsize-1; i >= 0; i--) { if (SERVICE_RECORD_MACRO(SRAMwordsRB[word - i])) { nr_sr++; nr_SR_detected++; fout << "Service Record found: " << "0x" << std::setfill('0') << std::setw(6) << std::hex << SRAMwordsRB[word - i] << std::dec << std::setfill(' ') << "in TRIGGER_ID = " << TRIGGER_NUMBER_MACRO2(SRAMwordsRB[word], SRAMwordsRB[word+1]) << endl; } } } // check for #dh inconsisty if (lv1 != nr_dh) { fout << "Found " << (lv1) << " DHs, expected " << nr_dh << " in TRIGGER_ID = " << TRIGGER_NUMBER_MACRO2(SRAMwordsRB[word], SRAMwordsRB[word+1]) << endl; nr_DH_inconsistent++; } windowsize = 0; nr_dr = 0; nr_sr = 0; lv1 = 0; lv1id++; if (error_detected) { fout << endl; fout << endl; fout << endl; fout << "# ---------- new trigger window -------------" << endl; } error_detected = false; word++; // needed because TRIGGER_ID is two bytes... }// end if trigger word } // end for word if (write_summary) { fout << "Summary:" << endl; fout << "# DR without DH found: " << nr_DR_wo_DH << endl; fout << "# SR found: " << nr_SR_detected << endl; fout << "# trigger windows with wrong amount of DH: " << nr_DH_inconsistent << endl; fout << "# LV1ID jumps found: " << nr_lv1_jumps << endl; fout << "# BCID jumps found: " << nr_bcid_jumps << endl; } return true; } bool ConfigRegister::WriteToTHisto(const char *filename) { ofstream fout; fout.open(filename); if (fout == NULL) return false; int data = 0; for (int col = 0; col < 80; col++) { for (int row = 0; row < 336; row++) { for (int tot = 0; tot < 16; tot++) { data = TOTHisto[col][row][tot]; if (data != 0) fout << "0" << "\t" << row << "\t" << col << "\t" << tot << "\t" << "0" << "\t" << data << endl; } } } fout.close(); return true; } bool ConfigRegister::WriteConfHisto(const char *filename) { ofstream fout; fout.open(filename); if (fout == NULL) return false; int data = 0; for (int col = 0; col < 80; col++) { for (int row = 0; row < 336; row++) { for (int step = 0; step < 1024; step++) { data = ConfHisto[col][row][step]; if (data != 0) fout << "0" << "\t" << row << "\t" << col << "\t" << step << "\t" << "0" << "\t" << data << endl; } } } fout.close(); return true; } void ConfigRegister::SetMeasurementMode(int mode) { WriteRegister(CS_FPGA_COUNT_MODE, mode); } void ConfigRegister::SetNumberOfEvents(int data) { unsigned char data_uc[4]; data_uc[0] = 0x000000ff & data; data_uc[1] = (0x0000ff00 & data) >> 8; data_uc[2] = (0x00ff0000 & data) >> 16; data_uc[3] = (0xff000000 & data) >>24; QMutexLocker locker(myUSB->getMutex()); myUSB->WriteExternal(CS_QTY_EVENTS_0, data_uc, 4); } int ConfigRegister::GetCountedEvents() { unsigned char eventsRB[4]; int events = 0; QMutexLocker locker(myUSB->getMutex()); myUSB->ReadExternal(CS_EVENT_COUNTER, eventsRB, 4); events = (eventsRB[3] << 24) + (eventsRB[2] << 16) + (eventsRB[1] << 8) + eventsRB[0]; return events; } void ConfigRegister::StartMeasurement() { // start time of source scan time(&start_time); // resetting event counter... WriteRegister(CS_EVENT_COUNTER, 0); WriteRegister(CS_EVENT_COUNTER + 1, 0); WriteRegister(CS_EVENT_COUNTER + 2, 0); WriteRegister(CS_EVENT_COUNTER + 3, 0); m_lengthLVL1 = ReadRegister(CS_L_LV1); // TODO: if possible get value from ConfigFEMemory WriteRegister(CS_MEASUREMENT_START_STOP, 0x01); // start measurement } void ConfigRegister::StopMeasurement() { // stop time of source scan //time(&stop_time); WriteRegister(CS_MEASUREMENT_START_STOP, 0x00); // stop measurement //while ((myUSB->HandlePresent() == true) && (ReadRegister(CS_SRAM_READOUT_READY) == 0)) // TODO //{ // ; //} } void ConfigRegister::PauseMeasurement() // pause measurement { //WriteRegister(CS_MEASUREMENT_PAUSE_RESUME, 1); WriteRegister(CS_MEASUREMENT_START_STOP, 0x00); // stop measurement, TODO: dummy at the moment //while ((myUSB->HandlePresent() == true) && (ReadRegister(CS_SRAM_READOUT_READY) == 0)) // TODO //{ // ; //} } void ConfigRegister::ResumeMeasurement() // resume measurement { //WriteRegister(CS_MEASUREMENT_PAUSE_RESUME, 0); WriteRegister(CS_MEASUREMENT_START_STOP, 0x01); // start measurement, TODO: dummy at the moment } // TODO: SRAMReadoutReady void ConfigRegister::GetSourceScanStatus(bool &SRAMFull, bool &MeasurementRunning, int &SRAMFillLevel, int &CollectedEvents, int &TriggerRate) { SRAMFillLevel = (ReadRegister(CS_SRAM_STATUS)*100)/255; // SRAM filling level in percent int dataRB = ReadRegister(CS_MEAS_STATUS); if ((dataRB & 0x01) == 0x01) MeasurementRunning = true; else MeasurementRunning = false; if ((dataRB & 0x02) == 0x02) SRAMFull = true; else SRAMFull = false; unsigned char trigger_rate[4]; QMutexLocker locker(myUSB->getMutex()); myUSB->ReadExternal(CS_TRIGGER_RATE_MEAS_0, trigger_rate, 4); TriggerRate = (trigger_rate[3] << 24) | (trigger_rate[2] << 16) | (trigger_rate[1] << 8) | trigger_rate[0]; // trigger rate in Hz unsigned char collected_events[4]; myUSB->ReadExternal(CS_EVENT_COUNTER, collected_events, 4); CollectedEvents = (collected_events[3] << 24) | (collected_events[2] << 16) | (collected_events[1] << 8) | collected_events[0]; } // readout of scan status bits and scan step void ConfigRegister::GetScanStatus(bool & scanReady, bool & scanCancelled, bool & scanError, int & scanStep) { // only for scan running on microcontroller //unsigned char dataRB[4]; //myUSB->ReadInterrupt(dataRB); //myUSB->ReadInterrupt(dataRB); // necessary to get recent data //scanBusy = (bool) (0x01 & (dataRB[2] >> 1)); // SCAN_BUSY //scanCancelled = (bool) (0x01 & (dataRB[2] >> 3)); // SCAN_CANCELLED //scanStep = (int) dataRB[3]; // Byte 1 to 3 (dataRB[0]...dataRB[2]) are reserved by FE-I3 project. Byte 4 (dataRB[3]) is available for use by the FE-I4 project. This is to keep the firmware compatible. // only for scan running host computer scanReady = m_scanReady; scanCancelled = m_scanCancelled; scanError = m_scanError; scanStep = m_scanStep; } // is set if scan has finished // in addition to that scanCancelled or scanError can be set to provide additional information void ConfigRegister::SetScanReady() { // only for scan running host computer m_scanReady = true; } // abort scan externally void ConfigRegister::SetScanCancelled() { // only for scan running host computer m_scanCancelled = true; } // internal scan error void ConfigRegister::SetScanError() { // only for scan running host computer m_scanError = true; } // resetting all scan status bits // should be done *before* StartScan() void ConfigRegister::ResetScanStatus() { // only for scan running host computer m_scanCancelled = false; m_scanError = false; m_scanReady = false; } int ConfigRegister::GetCurrentPhaseshift() { return current_phaseshift; } void ConfigRegister::SetCurrentPhaseshift(int value) { current_phaseshift = value; } bool ConfigRegister::CheckRX0State() { int state = ReadRegister(CS_EXT_INPUT_STATE); return (0x02 & state) > 0 ? true : false; } bool ConfigRegister::CheckRX1State() { int state = ReadRegister(CS_EXT_INPUT_STATE); return (0x04 & state) > 0 ? true : false; } bool ConfigRegister::CheckRX2State() { int state = ReadRegister(CS_EXT_INPUT_STATE); return (0x08 & state) > 0 ? true : false; } bool ConfigRegister::CheckExtTriggerState() { int state = ReadRegister(CS_EXT_INPUT_STATE); return (0x01 & state) > 0 ? true : false; } void ConfigRegister::FillHistosFromRawData() { int bcid = 0; int expected_bcid = 0; bool first_dh = true; int lv1id_internal = 0; int count = 0; for (int i = 0; i < SRAM_WORDSIZE; i++) { if (TRIGGER_WORD_MACRO(SRAMwordsRB[i])) i++; else if (DATA_HEADER_MACRO(SRAMwordsRB[i])) { if (first_dh) { first_dh = false; bcid = (FEI4B?DATA_HEADER_BCID_MACRO_FEI4B(SRAMwordsRB[i]):DATA_HEADER_BCID_MACRO(SRAMwordsRB[i])); expected_bcid = bcid; } else { expected_bcid = bcid + 1; if (FEI4B) { if (expected_bcid == 1024) // overflow expected_bcid = 0; } else { if (expected_bcid == 256) // overflow expected_bcid = 0; } bcid = (FEI4B?DATA_HEADER_BCID_MACRO_FEI4B(SRAMwordsRB[i]):DATA_HEADER_BCID_MACRO(SRAMwordsRB[i])); } if (bcid != expected_bcid) lv1id_internal = 0; else lv1id_internal++; } else if (DATA_RECORD_MACRO(SRAMwordsRB[i])) { HitHistoFromRawData[DATA_RECORD_COLUMN1_MACRO(SRAMwordsRB[i])-1][DATA_RECORD_ROW1_MACRO(SRAMwordsRB[i])-1] += 1; HitTOTHistoFromRawData[DATA_RECORD_COLUMN1_MACRO(SRAMwordsRB[i])-1][DATA_RECORD_ROW1_MACRO(SRAMwordsRB[i])-1][DATA_RECORD_TOT1_MACRO(SRAMwordsRB[i])] += 1; HitLV1HistoFromRawData[lv1id_internal] += 1; if (DATA_RECORD_TOT2_MACRO(SRAMwordsRB[i]) != 0xF) { HitHistoFromRawData[DATA_RECORD_COLUMN2_MACRO(SRAMwordsRB[i])-1][DATA_RECORD_ROW2_MACRO(SRAMwordsRB[i])-1] += 1; HitTOTHistoFromRawData[DATA_RECORD_COLUMN2_MACRO(SRAMwordsRB[i])-1][DATA_RECORD_ROW2_MACRO(SRAMwordsRB[i])-1][DATA_RECORD_TOT2_MACRO(SRAMwordsRB[i])] += 1; } } } } void ConfigRegister::GetSyncScanResult(double* dataX, double* dataY, int size) { if (0 <= size && size <= 201) { for (int i = 0; i < size; i++) { dataX[i] = SyncScanResultsX[i]; dataY[i] = SyncScanResultsY[i]; } } } void ConfigRegister::GetSRAMWordsRB(unsigned int* data, int size) { if (0 <= size && size <= SRAM_WORDSIZE) { for (int i = 0; i < size; i++) { data[i] = SRAMwordsRB[i]; } } }