/******************************************************************************* * Copyright (C) 2016 Vetle W. Ingeberg * * Author: Vetle Wegner Ingeberg, v.w.ingeberg@fys.uio.no * * * * --------------------------------------------------------------------------- * * This program is free software; you can redistribute it and/or modify it * * under the terms of the GNU General Public License as published by the * * Free Software Foundation; either version 3 of the license, or (at your * * option) any later version. * * * * This program is distributed in the hope that it will be useful, but * * WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * * Public License for more details. * * * * You should have recived a copy of the GNU General Public License along with * * the program. If not, see . * * * *******************************************************************************/ #include "UserSort.h" #include "DefineFile.h" #include "TDRWordBuffer.h" #include "DetectorRead.h" #include "Histogram1D.h" #include "Histogram2D.h" #include "Histograms.h" #include "Event.h" #include #include #include #include #include #define BIT15TO13 0xE000 #define BIT12TO0 0x1FFF inline uint16_t extract(const uint16_t &val, const int &begin, const int &end) { uint16_t mask = (1 << (end - begin)) - 1; return (val >> begin) & mask; } void showBit16(uint16_t u){ int values[16]; for (int i = 0 ; i < 16 ; i++){ values[i] = u%2; u = u/2; } for (int i = 15 ; i >= 0 ; i--){ std::cout << values[i]; } std::cout << std::endl; } double ExtractTime(const uint64_t ×tamp_100MHz, const uint16_t &cfddata) { uint64_t time_in_ns; uint16_t cfdtrigsource = ((cfddata & 0xE000) >> 13 ); if (cfdtrigsource != 7){ time_in_ns = 2*(cfdtrigsource - 1) + 10*timestamp_100MHz; } else { time_in_ns = 10*timestamp_100MHz; return static_cast(time_in_ns); } uint16_t timecfd = (cfddata & 0x1FFF) >> 0; double correction = 2.0*static_cast(timecfd)/8192.0; return static_cast(time_in_ns) + correction; } inline double ExtractCorrection(const uint16_t &cfddata) { uint16_t cfdtrigsource = ((cfddata & 0xE000) >> 13 ); double correction = 0.0; if (cfdtrigsource != 7){ correction = 2.0*(int(cfdtrigsource) - 1); } else { return 0.0; } uint16_t timecfd = ((cfddata & 0x1FFF) >> 0); correction += 2.0*timecfd/8192.0; return correction; } bool UserSort::UserCommand(const std::string &cmd){ return true; } void UserSort::CreateSpectra() { for (int i = 0 ; i < NUM_LABR ; ++i){ energy[i] = Spec("energy_L"+std::to_string(i+1), "raw energy spectrum", 16384, 0, 16384, "Energy [ch]"); energy_cal[i] = Spec("energy_cal_L"+std::to_string(i+1), "Energy calibrated", 2000, 0, 10000, "Energy [keV]"); time[i] = Mat("time_L"+std::to_string(i+1), "time spectrum", 6000, -30000, 30000, "Timediff. [ps]", NUM_LABR+1, 0, NUM_LABR+1, "LaBr detector no."); for (int j = 0 ; j < NUM_LABR ; ++j){ gg_spec[i][j] = Mat("gg_L"+std::to_string(i+1)+"_L"+std::to_string(j+1), "Gamma - gamma spectrum", 2000, 0, 10000, "Energy L"+std::to_string(i+1)+" [keV]", 2000, 0, 10000, "Energy L"+std::to_string(j+1)+" [keV]"); } } } bool UserSort::Sort(const Event &event) { for (int i = 0 ; i < NUM_LABR ; ++i){ n_L[i] = 0; } for (int i = 0 ; i < event.length ; ++i){ __builtin_prefetch(&event.words[i+1]); for (int j = 0 ; j < NUM_LABR ; ++j){ if (event.words[i].address == START_CHANNEL+j){ energy[j]->Fill(event.words[i].adcdata); energy_cal[j]->Fill(GainEnergy(event.words[i].address, event.words[i].adcdata)); if (n_L[j] < 128){ w_L[j][n_L[j]] = event.words[i]; ++n_L[j]; } break; } } } double E0, t0_fine; int64_t t0_course; double E1, t1_fine; int64_t t1_course; double timediff_c, timediff_f, timediff; for (int i = 0 ; i < NUM_LABR ; ++i){ for (int j = 0 ; j < n_L[i] ; ++j){ __builtin_prefetch(&w_L[i][j+1]); E0 = GainEnergy(w_L[i][j].address, w_L[i][j].adcdata); t0_course = w_L[i][j].timestamp*10; t0_fine = ExtractCorrection(w_L[i][j].cfddata); for (int n = 0 ; n < NUM_LABR ; ++n){ for (int m = 0 ; m < n_L[n] ; ++m){ __builtin_prefetch(&w_L[n][m+1]); if (n == i && m == j){ break; } E1 = GainEnergy(w_L[n][m].address, w_L[n][m].adcdata); t1_course = w_L[n][m].timestamp*10; t1_fine = ExtractCorrection(w_L[n][m].cfddata); timediff_c = t0_course - t1_course; timediff_f = t0_fine - t1_fine; timediff = (timediff_c + timediff_f)*1000.; time[i]->Fill(timediff, n+0.5); if ( (i != n) && GateTime(w_L[i][j].address, w_L[n][m].address, timediff) ){ gg_spec[i][n]->Fill(E0, E1); } } } } } return true; } bool UserSort::End() { return true; }