00001 #include "PulseCandidateFinder.h"
00002 #include "SetupNavigator.h"
00003 #include "definitions.h"
00004 #include "debug_tools.h"
00005 #include "AlcapExcept.h"
00006
00007 #include <iostream>
00008 #include <iterator>
00009 #include <sstream>
00010 #include <fstream>
00011 #include <cstdlib>
00012 #include <cmath>
00013
00014 #include <TSQLiteServer.h>
00015 #include <TSQLiteResult.h>
00016 #include <TSQLiteRow.h>
00017
00018 MAKE_EXCEPTION(PulseCandidateFinder, Base);
00019 MAKE_EXCEPTION(UnspecifiedChannel,PulseCandidateFinder);
00020
00022 PulseCandidateFinder::PulseCandidateFinder():
00023 fChannel(IDs::kErrorDetector),
00024 fParameterValue(definitions::DefaultValue),
00025 fNoise(definitions::DefaultValue),
00026 fPedestal(definitions::DefaultValue),
00027 fNSigma(definitions::DefaultValue){
00028
00029
00030 if (fDefaultParameterValues.empty()) {
00031 SetDefaultParameterValues();
00032 }
00033
00034 }
00035
00037 PulseCandidateFinder::PulseCandidateFinder(std::string detname, modules::options* opts) {
00038
00039
00040 if (fDefaultParameterValues.empty()) {
00041 SetDefaultParameterValues();
00042 }
00043
00044 SetChannel(detname);
00045
00046
00047 if(opts->HasOption("n_sigma")){
00048 SetSigma( opts->GetInt("n_sigma"));
00049 } else if(opts->HasOption(detname+"_param")){
00050 fParameterValue = opts->GetDouble(detname+"_param");
00051 }
00052
00053
00054 if (opts->GetFlag("debug")){
00055 std::cout << "Parameter Value for " << fChannel
00056 << " PulseCandidateFinder is "
00057 << fParameterValue << std::endl;
00058 }
00059 }
00060
00061 void PulseCandidateFinder::SetSigma( double sigma){
00062 fNSigma=sigma;
00063 fParameterValue=fNSigma*fNoise;
00064 }
00065
00066 void PulseCandidateFinder::SetChannel(const std::string& detname){
00067 fChannel=detname;
00068 fNoise = SetupNavigator::Instance()->GetNoise(fChannel);
00069 fPedestal = SetupNavigator::Instance()->GetPedestal(fChannel);
00070 fParameterValue = fDefaultParameterValues[fChannel];
00071 }
00072
00075 void PulseCandidateFinder::FindPulseCandidates(const TPulseIsland* pulse) {
00076 if(!fChannel.isValid()){
00077 std::cout<<"Channel for PCF is not set, make sure to use "
00078 "SetChannel() if you used the defualt constructor"<<std::endl;
00079 throw Except::UnspecifiedChannel();
00080 }
00081
00082
00083 fPulseCandidateLocations.clear();
00084
00085 fPulseIsland = pulse;
00086
00087
00088
00089
00090 if (fNSigma != 0) {
00091 FindCandidatePulses_Slow(fParameterValue);
00092 }
00093 else {
00094 if (fChannel.isFast()) {
00095 if (fChannel.Detector() != IDs::kGe) {
00096 FindCandidatePulses_Slow(fParameterValue);
00097 }
00098 else {
00099 FindCandidatePulses_Fast(fParameterValue);
00100 }
00101 }
00102 else if (fChannel.isSlow()) {
00103 FindCandidatePulses_Slow(fParameterValue);
00104 }
00105 else {
00106
00107 FindCandidatePulses_Fast(fParameterValue);
00108 }
00109 }
00110
00111 }
00112
00113 PulseCandidateFinder::~PulseCandidateFinder() {
00114 }
00115
00118 void PulseCandidateFinder::GetPulseCandidates(std::vector<TPulseIsland*>& pulse_candidates)const {
00119
00120
00121 std::vector<int>::const_iterator start_new, stop_new;
00122 for (std::vector<Location>::const_iterator locationIter = fPulseCandidateLocations.begin();
00123 locationIter != fPulseCandidateLocations.end(); ++locationIter) {
00124
00125
00126 start_new=fPulseIsland->GetSamples().begin();
00127 std::advance(start_new,locationIter->start);
00128
00129
00130 stop_new=fPulseIsland->GetSamples().begin();
00131 std::advance(stop_new,locationIter->stop);
00132
00133
00134 std::string bankname = fPulseIsland->GetBankName();
00135 int new_timestamp = fPulseIsland->GetTimeStamp() + locationIter->start;
00136
00137
00138 int index=locationIter-fPulseCandidateLocations.begin();
00139 if((int)pulse_candidates.size() <= index || !pulse_candidates.at(index)){
00140 TPulseIsland* pulse_island = new TPulseIsland(new_timestamp, start_new, stop_new, bankname);
00141 pulse_candidates.push_back(pulse_island);
00142 }else{
00143 TPulseIsland* pulse_island=pulse_candidates.at(index);
00144 pulse_island->SetSamples(start_new,stop_new);
00145 pulse_island->SetTimeStamp(new_timestamp);
00146 pulse_island->SetBankName(bankname);
00147 }
00148 }
00149 for(unsigned int i=fPulseCandidateLocations.size();i< pulse_candidates.size();++i){
00150 pulse_candidates.at(i)->Reset();
00151 }
00152 }
00153
00156 void PulseCandidateFinder::FindCandidatePulses_Fast(int rise) {
00157
00158 const std::vector<int>& samples = fPulseIsland->GetSamples();
00159 unsigned int n_samples = samples.size();
00160
00161 std::string bankname = fPulseIsland->GetBankName();
00162 int polarity = fPulseIsland->GetTriggerPolarity();
00163
00164 int s1, s2, ds;
00165 bool found = false;
00166 Location location;
00167
00168
00169 int n_before_start_samples = 2;
00170 for (unsigned int i = 1; i < n_samples; ++i) {
00171 s1 = polarity * (samples[i-1] - fPedestal);
00172 s2 = polarity * (samples[i] - fPedestal);
00173 ds = s2 - s1;
00174
00175 if (found) {
00176
00177 if (s2 < fNoise) {
00178 location.stop = (int)i;
00179 if (location.stop >= (int)samples.size()) {
00180 location.stop = samples.size() - 1;
00181 }
00182
00183 fPulseCandidateLocations.push_back(location);
00184 found = false;
00185 }
00186 else if (i == n_samples-1) {
00187 location.stop = (int) i;
00188
00189 fPulseCandidateLocations.push_back(location);
00190 found = false;
00191 }
00192 } else {
00193 if (ds > rise) {
00194 found = true;
00195 location.start = (int)(i - 1) - n_before_start_samples;
00196
00197 if (location.start < 0) {
00198 location.start = 0;
00199 }
00200 }
00201 }
00202 }
00203 }
00204
00207 void PulseCandidateFinder::FindCandidatePulses_Slow(int threshold) {
00208
00209 const std::vector<int>& samples = fPulseIsland->GetSamples();
00210 unsigned int n_samples = samples.size();
00211
00212 std::string bankname = fPulseIsland->GetBankName();
00213 int polarity = fPulseIsland->GetTriggerPolarity();
00214
00215 int sample_height;
00216 int start, stop;
00217 bool found = false;
00218 Location location;
00219
00220
00221 for (unsigned int i = 0; i < n_samples; ++i) {
00222 sample_height = polarity * (samples[i] - fPedestal);
00223
00224 if (found) {
00225 if (sample_height < fNoise) {
00226 location.stop = (int)i;
00227 if (location.stop >=(int) samples.size()) {
00228 location.stop = samples.size() - 1;
00229 }
00230
00231 start = stop = 0;
00232 fPulseCandidateLocations.push_back(location);
00233 found = false;
00234 }
00235 else if (i == n_samples-1) {
00236 location.stop = (int) i;
00237
00238 fPulseCandidateLocations.push_back(location);
00239 found = false;
00240 }
00241 } else {
00242 if (sample_height > threshold) {
00243 found = true;
00244
00245
00246 location.start = (int)(i);
00247 for (int j = i; j > 0; --j) {
00248
00249 sample_height = polarity * (samples[j] - fPedestal);
00250 if (sample_height <= 0) {
00251 location.start = (int)(j);
00252 break;
00253 }
00254 else if (j == 1) {
00255 location.start = 0;
00256 }
00257 }
00258 if (location.start < 0) {
00259 location.start = 0;
00260 }
00261 }
00262 }
00263 }
00264 }
00265
00266
00269 void PulseCandidateFinder::FillParameterHistogram(TH2D* histogram) {
00270
00271 std::string detname = TSetupData::Instance()->GetDetectorName(fPulseIsland->GetBankName());
00272 IDs::channel theChannel = detname;
00273
00274
00275 const std::vector<int>& samples = fPulseIsland->GetSamples();
00276 unsigned int n_samples = samples.size();
00277 int polarity = fPulseIsland->GetTriggerPolarity();
00278
00279 int s1, s2, ds;
00280
00281
00282 for (unsigned int i = 1; i < n_samples; ++i) {
00283 s1 = polarity * (samples[i-1] - fPedestal);
00284 s2 = polarity * (samples[i] - fPedestal);
00285 ds = s2 - s1;
00286
00287 histogram->Fill(ds, s1);
00288 }
00289
00290 std::stringstream histtitle;
00291 histtitle << "Plot of sample differences vs sample heights for " << detname << " for Run " << SetupNavigator::Instance()->GetRunNumber();
00292 histogram->SetTitle(histtitle.str().c_str());
00293 histogram->GetYaxis()->SetTitle("Sample Heights");
00294 histogram->GetXaxis()->SetTitle("Sample Differences");
00295 }
00296
00298 std::map<IDs::channel, int> PulseCandidateFinder::fDefaultParameterValues;
00299
00302 void PulseCandidateFinder::SetDefaultParameterValues() {
00303
00304
00305 fDefaultParameterValues[IDs::channel("muSc")] = 230;
00306 fDefaultParameterValues[IDs::channel("muScA")] = 100;
00307 fDefaultParameterValues[IDs::channel("NDet")] = 100;
00308 fDefaultParameterValues[IDs::channel("NDet2")] = 100;
00309
00310 fDefaultParameterValues[IDs::channel("Ge-F")] = 40;
00311
00312 fDefaultParameterValues[IDs::channel("ScL")] = 100;
00313 fDefaultParameterValues[IDs::channel("ScR")] = 100;
00314 fDefaultParameterValues[IDs::channel("ScGe")] = 20;
00315 fDefaultParameterValues[IDs::channel("ScVe")] = 100;
00316
00317 fDefaultParameterValues[IDs::channel("SiL2-F")] = 300;
00318 fDefaultParameterValues[IDs::channel("SiL1-1-F")] = 130;
00319 fDefaultParameterValues[IDs::channel("SiL1-2-F")] = 500;
00320 fDefaultParameterValues[IDs::channel("SiL1-3-F")] = 135;
00321 fDefaultParameterValues[IDs::channel("SiL1-4-F")] = 140;
00322
00323 fDefaultParameterValues[IDs::channel("SiR2-F")] = 300;
00324 fDefaultParameterValues[IDs::channel("SiR1-1-F")] = 135;
00325 fDefaultParameterValues[IDs::channel("SiR1-2-F")] = 140;
00326 fDefaultParameterValues[IDs::channel("SiR1-3-F")] = 140;
00327 fDefaultParameterValues[IDs::channel("SiR1-4-F")] = 150;
00328
00329
00330 fDefaultParameterValues[IDs::channel("Ge-S")] = 500;
00331
00332 fDefaultParameterValues[IDs::channel("SiL2-S")] = 100;
00333 fDefaultParameterValues[IDs::channel("SiL1-1-S")] = 50;
00334 fDefaultParameterValues[IDs::channel("SiL1-2-S")] = 80;
00335 fDefaultParameterValues[IDs::channel("SiL1-3-S")] = 120;
00336 fDefaultParameterValues[IDs::channel("SiL1-4-S")] = 80;
00337
00338 fDefaultParameterValues[IDs::channel("SiR2-S")] = 100;
00339 fDefaultParameterValues[IDs::channel("SiR1-1-S")] = 50;
00340 fDefaultParameterValues[IDs::channel("SiR1-2-S")] = 65;
00341 fDefaultParameterValues[IDs::channel("SiR1-3-S")] = 65;
00342 fDefaultParameterValues[IDs::channel("SiR1-4-S")] = 62;
00343 }
00344
00345 bool PulseCandidateFinder::CheckDigitiserOverflow() {
00346 const std::vector<int>& samples = fPulseIsland->GetSamples();
00347 unsigned int n_samples = samples.size();
00348
00349 std::string bankname = fPulseIsland->GetBankName();
00350 int n_bits = TSetupData::Instance()->GetNBits(bankname);
00351 double max_adc_value = std::pow(2, n_bits);
00352 bool overflowed = false;
00353
00354
00355 for (unsigned int i = 0; i < n_samples; ++i) {
00356 if (samples[i] >= max_adc_value) {
00357 overflowed = true;
00358 break;
00359 }
00360 }
00361
00362 return overflowed;
00363 }