00001 #include "PulseViewer.h"
00002 #include "RegisterModule.inc"
00003 #include "TGlobalData.h"
00004 #include "TSetupData.h"
00005 #include "ModulesOptions.h"
00006 #include "ExportPulse.h"
00007 #include "TAnalysedPulse.h"
00008 #include "ModulesParser.h"
00009 #include "debug_tools.h"
00010 #include "IdSource.h"
00011 #include "EventNavigator.h"
00012 #include "TIntegralRatioAnalysedPulse.h"
00013 #include "TTemplateFitAnalysedPulse.h"
00014 #include "TTemplateConvolveAnalysedPulse.h"
00015
00016 #include <TFormula.h>
00017
00018 #include <algorithm>
00019 #include <iostream>
00020 #include <iomanip>
00021 using std::cout;
00022 using std::endl;
00023 using modules::parser::GetOneWord;
00024 using modules::parser::GetDouble;
00025
00026 #define GetVals(array,pulse)\
00027 for(ParameterKeys::const_iterator i_key=fAvailableParams.begin(); \
00028 i_key!=fAvailableParams.end();++i_key){\
00029 array[i_key->second]=GetParameterValue(pulse,i_key->second);\
00030 }
00031
00032 extern SourceAnalPulseMap gAnalysedPulseMap;
00033
00034 PulseViewer::ParameterKeys PulseViewer::fAvailableParams;
00035 PulseViewer::PulseKeys PulseViewer::fAvailablePulseTypes;
00036
00037 PulseViewer::PulseViewer(modules::options* opts):
00038 BaseModule("PulseViewer",opts),fTotalPlotted(0),fFormula(NULL),fEvent(0){
00039 fRequestedSource=opts->GetString("source");
00040 fRequestedPulseType=opts->GetString("pulse_type","TAnalysedPulse");
00041 fSource.Channel()=fRequestedSource;
00042 fTriggerCondition=opts->GetString("trigger");
00043 fSummarize=opts->GetFlag("summarize");
00044 fMaxToPlot=opts->GetInt("max_plots",-1);
00045 fMaxToPlotPerEvent=opts->GetInt("max_plots_event",-1);
00046 fStopAtMax=opts->GetBool("stop_at_max_plots",true);
00047 }
00048
00049 PulseViewer::~PulseViewer(){
00050 if(fFormula) delete fFormula;
00051 }
00052
00053 int PulseViewer::BeforeFirstEntry(TGlobalData* gData, const TSetupData* setup){
00054
00055
00056 if(!ExportPulse::Instance()){
00057 cout<<"PulseViewer: Error: You need to run with ExportPulse to use PulseViewer module"<<std::endl;
00058 return 1;
00059 }
00060
00061
00062 if(!fSource.Channel().isValid()){
00063 cout<<"PulseViewer: Error: No detector called '"<<fRequestedSource<<"' exists"<<endl;
00064 return 2;
00065 }
00066
00067
00068 if(fAvailableParams.empty()){
00069 fAvailableParams["amplitude"]=kAmplitude;
00070 fAvailableParams["time"]=kTime;
00071 fAvailableParams["TPI_length"]=kTPILength;
00072 fAvailableParams["integral"]=kIntegral;
00073 fAvailableParams["energy"]=kEnergy;
00074 fAvailableParams["pedestal"]=kPedestal;
00075 fAvailableParams["trigger_time"]=kTriggerTime;
00076 fAvailableParams["event_no"]=kEventNo;
00077 }
00078
00079 if(fAvailablePulseTypes.empty()){
00080 fAvailablePulseTypes["TAnalysedPulse"]=kTAP;
00081 fAvailablePulseTypes["IntegralRatioAP"]=kIntegralRatioAP;
00082 fAvailablePulseTypes["TemplateFitAP"]=kTemplateFitAP;
00083 fAvailablePulseTypes["TemplateConvolveAP"]=kTemplateConvolveAP;
00084 }
00085
00086 int ret_val= CheckPulseType(fRequestedPulseType);
00087 if(ret_val) return ret_val;
00088
00089
00090 return ParseTriggerString(fTriggerCondition);
00091 }
00092
00093 int PulseViewer::CheckPulseType(const std::string& pulse_type){
00094 PulseKeys::const_iterator i_type=fAvailablePulseTypes.find(pulse_type);
00095 if(i_type==fAvailablePulseTypes.end()) {
00096 cout<<"PulseViewer::CheckPulseType: Error: Bad pulse_type: "<<pulse_type<<endl;
00097 for(PulseKeys::const_iterator it=fAvailablePulseTypes.begin();
00098 it!=fAvailablePulseTypes.end(); it++){
00099 cout<<" |-"<<it->first<<endl;
00100 }
00101 return 1;
00102 }
00103 fPulseType=i_type->second;
00104 switch(fPulseType){
00105 case kTAP: break;
00106 case kTemplateConvolveAP:
00107 fAvailableParams["NPeaks"]=kNPeaks;
00108 fAvailableParams["PeakRank"]=kPeakRank;
00109 fAvailableParams["Integral_ratio"]=kIntegralRatio;
00110 break;
00111 case kTemplateFitAP:
00112 fAvailableParams["Chi2"]=kChi2;
00113 fAvailableParams["Status"]=kStatus;
00114 fAvailableParams["Integral_ratio"]=kIntegralRatio;
00115 fAvailableParams["Double_fitted"]=kWasDouble;
00116 break;
00117 case kIntegralRatioAP:
00118 fAvailableParams["Integral_ratio"]=kIntegralRatio;
00119 fAvailableParams["Integral_tail"]=kIntegralTail;
00120 break;
00121 }
00122 return 0;
00123 }
00124
00125 int PulseViewer::ParseTriggerString(const std::string& trigger_condition){
00126 std::string expression =fTriggerCondition;
00127 for(ParameterKeys::const_iterator i_key=fAvailableParams.begin();
00128 i_key!=fAvailableParams.end();i_key++){
00129 modules::parser::ReplaceWords(expression,i_key->first,Form("[%d]",i_key->second));
00130 }
00131
00132 fFormula=new TFormula("PulseViewerTrigger",expression.c_str());
00133 int ret= fFormula->Compile();
00134 if(ret){
00135 cout<<"Error: Bad trigger expression: '"<<fTriggerCondition<<"'"<<endl;
00136 cout<<" Only use parameters from"<<endl;
00137 for(ParameterKeys::const_iterator it=fAvailableParams.begin();
00138 it!=fAvailableParams.end();
00139 it++){
00140 cout<<" |-"<<it->first<<endl;
00141 }
00142 }
00143 return ret;
00144 }
00145
00146 int PulseViewer::ProcessEntry(TGlobalData* gData, const TSetupData* setup){
00147
00148 if(fMaxToPlot>0 && fTotalPlotted>=fMaxToPlot){
00149 if(fStopAtMax){
00150 cout<<"PulseViewer::ProcessEntry: "<<fTotalPlotted<<" pulses have already been drawn which "
00151 <<"is greater than the limit of "<<fMaxToPlot<<" so I'm stopping execution.\n";
00152
00153 return 1;
00154 }
00155 return 0;
00156 }
00157
00158
00159 AnalysedPulseList* allTAPs=NULL;
00160 for(SourceAnalPulseMap::iterator i_source=gAnalysedPulseMap.begin();
00161 i_source!=gAnalysedPulseMap.end(); ++i_source){
00162 if(i_source->first.matches(GetSource())){
00163 allTAPs=&i_source->second;
00164 break;
00165 }
00166 }
00167
00168 if(!allTAPs){
00169 cout<<"Problem getting TAP list for "<<GetSource()<<endl;
00170 return 1;
00171 }else if(allTAPs->empty() ){
00172 if(Debug()) cout<<"List of TAPS for '"<< GetSource()<<"' was empty "<<endl;
00173 return 0;
00174 }
00175
00176
00177 int retVal=0;
00178 for(AnalysedPulseList::iterator i_pulse=allTAPs->begin();
00179 i_pulse!=allTAPs->end() && retVal==0;
00180 i_pulse++){
00181 if(fEvent==0){
00182 retVal=TestPulseType(*i_pulse);
00183 }
00184 retVal=ConsiderDrawing((*i_pulse)->GetParentID() ,*i_pulse);
00185 }
00186 if(retVal!=0) return retVal;
00187
00188 fEvent++;
00189
00190 return 0;
00191 }
00192
00193 bool PulseViewer::TestPulseType(const TAnalysedPulse* pulse){
00194 switch(fPulseType){
00195 case kTAP: return false;
00196 case kIntegralRatioAP: return dynamic_cast<const TIntegralRatioAnalysedPulse*>(pulse);
00197 case kTemplateFitAP: return dynamic_cast<const TTemplateFitAnalysedPulse*>(pulse);
00198 case kTemplateConvolveAP: return dynamic_cast<const TTemplateConvolveAnalysedPulse*>(pulse);
00199 }
00200 return false;
00201 }
00202
00203 double PulseViewer::GetParameterValue(const TAnalysedPulse* pulse,const ParameterType& parameter){
00204 double retVal=0;
00205 switch (parameter){
00206 case kAmplitude: retVal=pulse->GetAmplitude(); break;
00207 case kTime: retVal=pulse->GetTime(); break;
00208 case kIntegral: retVal=pulse->GetIntegral(); break;
00209 case kTPILength: retVal=pulse->GetTPILength(); break;
00210 case kEnergy: retVal=pulse->GetEnergy(); break;
00211 case kPedestal: retVal=pulse->GetPedestal(); break;
00212 case kTriggerTime: retVal=pulse->GetTriggerTime(); break;
00213 case kEventNo: retVal=fEvent; break;
00214 default: retVal=definitions::DefaultValue;
00215 cout<<"PulseViewer::GetParameterValue: Error: Cannot get param: "<<parameter<<" from a TAnalysedPulse"<<endl;
00216 }
00217 return retVal;
00218 }
00219
00220 double PulseViewer::GetParameterValue(const TIntegralRatioAnalysedPulse* pulse,const ParameterType& parameter){
00221 double retVal=0;
00222 switch (parameter){
00223 case kIntegralTail: retVal=pulse->GetIntegralSmall(); break;
00224 case kIntegralRatio: retVal=pulse->GetIntegralRatio(); break;
00225 default: retVal=GetParameterValue( static_cast<const TAnalysedPulse*>(pulse),parameter);
00226 }
00227 return retVal;
00228 }
00229
00230 double PulseViewer::GetParameterValue(const TTemplateFitAnalysedPulse* pulse,const ParameterType& parameter){
00231 double retVal=0;
00232 switch (parameter){
00233 case kIntegralRatio: retVal=pulse->GetIntegralRatio(); break;
00234 case kChi2: retVal=pulse->GetChi2(); break;
00235 case kStatus: retVal=pulse->GetFitStatus(); break;
00236 case kWasDouble: retVal=pulse->WasFirstOfDouble(); break;
00237 default: retVal=GetParameterValue( static_cast<const TAnalysedPulse*>(pulse),parameter);
00238 }
00239 return retVal;
00240 }
00241
00242 double PulseViewer::GetParameterValue(const TTemplateConvolveAnalysedPulse* pulse,const ParameterType& parameter){
00243 double retVal=0;
00244 switch (parameter){
00245 case kIntegralRatio: retVal=pulse->GetIntegralRatio(); break;
00246 case kNPeaks: retVal=pulse->GetNPeaks(); break;
00247 case kPeakRank: retVal=pulse->GetPeakRank(); break;
00248 default: retVal=GetParameterValue( static_cast<const TAnalysedPulse*>(pulse),parameter);
00249 }
00250 return retVal;
00251 }
00252
00253 int PulseViewer::ConsiderDrawing(const TAnalysedPulseID& id, const TAnalysedPulse* pulse){
00254
00255 double vals[fAvailableParams.size()];
00256 switch (fPulseType){
00257 case kTAP: GetVals(vals,pulse); break;
00258 case kTemplateConvolveAP: if(true){
00259 const TTemplateConvolveAnalysedPulse* tc_pulse =static_cast<const TTemplateConvolveAnalysedPulse*>(pulse);
00260 GetVals(vals,tc_pulse);
00261 } break;
00262 case kTemplateFitAP: if(true){
00263 const TTemplateFitAnalysedPulse* tf_pulse =static_cast<const TTemplateFitAnalysedPulse*>(pulse);
00264 GetVals(vals,tf_pulse);
00265 } break;
00266 case kIntegralRatioAP: if(true){
00267 const TIntegralRatioAnalysedPulse* ir_pulse =static_cast<const TIntegralRatioAnalysedPulse*>(pulse);
00268 GetVals(vals,ir_pulse);
00269 } break;
00270 }
00271 fFormula->SetParameters(vals);
00272 double value=fFormula->Eval(0);
00273 if(!value) return 0;
00274 if(Debug()){
00275 cout<<"PulseViewer: Event: "<<EventNavigator::Instance().EntryNo()
00276 <<" Plotting pulse "<<id<<" [ "<<fTriggerCondition<<" => "<<fFormula->GetExpFormula("P")<<" ]"<<endl;
00277 }
00278
00279
00280
00281
00282 if(fPulsesPlotted[EventNavigator::Instance().EntryNo()].count(id)==0){
00283 ExportPulse::Instance()->AddToExportList(pulse);
00284 fTotalPlotted++;
00285 }
00286 fPulsesPlotted[EventNavigator::Instance().EntryNo()][id]++;
00287 return 0;
00288 }
00289
00290 int PulseViewer::AfterLastEntry(TGlobalData* gData, const TSetupData* setup){
00291
00292
00293 if(SummarisePlots()){
00294 const std::string prefix=" ";
00295 cout<<"Summary for pulse criteria: ("<<fTriggerCondition <<") on channel "<<fSource<<endl;
00296 if(!fPulsesPlotted.empty()){
00297 cout<<prefix<<" Event | Pulse IDs drawn (sub_pulse ID)"<<endl;
00298 cout<<prefix<<" ----- | ------------ "<<endl;
00299 for(EventPulseIDList_t::const_iterator i_event=fPulsesPlotted.begin();
00300 i_event!=fPulsesPlotted.end();i_event++){
00301 cout<<prefix<<std::setw(6)<< i_event->first<<" | ";
00302 for(PulseIDList_t::const_iterator i_pulse=i_event->second.begin();
00303 i_pulse!=i_event->second.end();i_pulse++){
00304 cout<<std::setw(2)<< i_pulse->first <<"("<< i_pulse->second<<")" <<", ";
00305 }
00306 cout<<endl;
00307 }
00308 cout<<prefix<<" ----- | ------------ "<<endl;
00309 }
00310 cout<<prefix<<"Total pulses plotted = "<<fTotalPlotted<<endl;
00311 cout<<"Summary for pulse criteria: ("<<fTriggerCondition <<") on channel "<<fSource<<endl;
00312
00313 }
00314
00315 return 0;
00316 }
00317
00318 ALCAP_REGISTER_MODULE(PulseViewer,source,trigger,pulse_type,summarize);