00001 #include "ExportPulse.h"
00002
00003
00004 #include <iostream>
00005 #include <algorithm>
00006 #include <utility>
00007 #include <sstream>
00008 #include <stdexcept>
00009
00010
00011 #include <TH1F.h>
00012 #include <THStack.h>
00013 #include <TDirectory.h>
00014
00015
00016 #include "ModulesFactory.h"
00017 #include "ModulesParser.h"
00018 #include "ModulesNavigator.h"
00019 #include "TVAnalysedPulseGenerator.h"
00020 #include "MaxBinAPGenerator.h"
00021 #include "RegisterModule.inc"
00022 #include "EventNavigator.h"
00023 #include "SetupNavigator.h"
00024 #include "debug_tools.h"
00025
00026 using std::cout;
00027 using std::endl;
00028 using std::string;
00029
00030
00031 extern Long64_t* gTotalEntries;
00032
00033
00034 ExportPulse::ExportPulse(modules::options* opts)
00035 : BaseModule("ExportPulse",opts),fGuidanceShown(false)
00036 , fSetup(NULL), fOptions(opts), fPulseFinder(NULL)
00037 {
00038 fPulseInfo.pulseID=-1;
00039 fPulseInfo.event=-1;
00040 fPulseInfo.bankname="";
00041 fPulseInfo.detname="";
00042
00043 fUsePCF=opts->GetFlag("run_pulse_finder");
00044 if(fUsePCF){
00045 fPulseFinder=new PulseCandidateFinder();
00046 }
00047
00048 fTPIDirectory=GetDirectory("TPIs");
00049 fTAPDirectory=GetDirectory("TAPs");
00050 }
00051
00052
00053
00054 ExportPulse::~ExportPulse()
00055 {}
00056
00057
00058
00059 int ExportPulse::BeforeFirstEntry(TGlobalData* gData, const TSetupData* setup){
00060 fSetup=setup;
00061 if(!fSetup){
00062 cout<<"Error: TSetupData passed to ExportPulse is NULL..."<<endl;
00063 return 1 ;
00064 }
00065 fTotalEvents = EventNavigator::Instance().GetInputNEntries();
00066
00068 if(fOptions){
00069 int num=0;
00070 std::vector<std::string> currentList;
00071 std::vector<EventID_t> event_list;
00072 std::vector<TPulseIslandID> pulse_list;
00073 modules::parser::Constructor_t event_pulse_request;
00074 std::string error_type;
00075
00076 for(modules::options::OptionsList_t::const_iterator i_opt = fOptions->begin();
00077 i_opt != fOptions->end(); i_opt++){
00078
00079 if( i_opt->first != "all" && fSetup->GetBankName(i_opt->first)=="") continue;
00080
00081
00082 currentList.clear();
00083 event_list.clear();
00084 pulse_list.clear();
00085 num=fOptions->GetVectorStringsByDelimiter(i_opt->first,currentList);
00086 if(num<=0) continue;
00087
00088 for(std::vector<std::string>::iterator i_request=currentList.begin();
00089 i_request!=currentList.end();
00090 i_request++){
00091 event_pulse_request=modules::parser::ParseConstructor(*i_request,'(',')');
00092
00093 if(event_pulse_request.before=="" )error_type="event";
00094 else if( event_pulse_request.inside=="")error_type="pulse";
00095 else if( !ParseEventRequest(event_pulse_request.before, event_list)) error_type="event";
00096 else if( !ParsePulseRequest(event_pulse_request.inside,pulse_list)) error_type="pulse";
00097 if(error_type != ""){
00098 cout<<"Skipping badly formatted "<<error_type<<" specification: "<<*i_request<<endl;
00099 cout<<"event="<<event_pulse_request.before<<", pulse="<<event_pulse_request.inside<<endl;
00100 ShowGuidance();
00101 continue;
00102 }
00103
00104 for(std::vector<EventID_t>::const_iterator i_event=event_list.begin();
00105 i_event!=event_list.end();
00106 i_event++){
00107 for(std::vector<TPulseIslandID>::const_iterator i_pulse=pulse_list.begin();
00108 i_pulse!=pulse_list.end(); i_pulse++){
00109 AddToConfigRequestList(*i_event,i_opt->first,*i_pulse);
00110 }
00111 }
00112 }
00113 }
00114 }
00115 return 0;
00116 }
00117
00118
00119
00120 int ExportPulse::ProcessEntry(TGlobalData *gData, const TSetupData* gSetup){
00121
00122 fGlobalData=gData;
00123 SetCurrentEventNumber(EventNavigator::Instance().EntryNo());
00124
00125
00126 LoadPulsesRequestedByConfig();
00127
00128 fTPIDirectory->cd();
00129 int ret_val=DrawTPIs();
00130 if(ret_val!=0) return ret_val;
00131
00132 fTAPDirectory->cd();
00133 ret_val=DrawTAPs();
00134 if(ret_val!=0) return ret_val;
00135
00136 ClearPulsesToExport();
00137 return 0;
00138 }
00139
00140
00141
00142 int ExportPulse::DrawTAPs(){
00143
00144 const TAPList_t* requestedPulses;
00145
00146
00147 for(ChannelTAPs_t::const_iterator i_detector=fTAPsToPlot.begin();
00148 i_detector!=fTAPsToPlot.end();
00149 i_detector++){
00150 SetCurrentDetectorName(i_detector->first);
00151
00152
00153 requestedPulses=&(i_detector->second);
00154
00155
00156 for(TAPList_t::const_iterator i_pulse=requestedPulses->begin();
00157 i_pulse!=requestedPulses->end();
00158 i_pulse++){
00159
00160 SetCurrentPulseID((*i_pulse)->GetParentID());
00161
00162 PlotTAP(*i_pulse,fPulseInfo);
00163
00164 }
00165 }
00166 return 0;
00167 }
00168
00169
00170
00171 int ExportPulse::DrawTPIs(){
00172
00173 TPulseIsland* pulse;
00174 const PulseIDList_t* requestedPulses;
00175 PulseIslandList* pulseList;
00176
00177
00178 for(ChannelPulseIDs_t::const_iterator i_detector=fTPIsToPlot.begin();
00179 i_detector!=fTPIsToPlot.end();
00180 i_detector++){
00181 SetCurrentDetectorName(i_detector->first);
00182
00183
00184 requestedPulses=&(i_detector->second);
00185 pulseList=GetTPIsFromDetector();
00186
00187
00188 for(PulseIDList_t::const_iterator i_pulseID=requestedPulses->begin();
00189 i_pulseID!=requestedPulses->end();
00190 i_pulseID++){
00191
00192 SetCurrentPulseID(*i_pulseID);
00193
00194
00195 try{
00196 pulse=pulseList->at(*i_pulseID);
00197 }
00198 catch(const std::out_of_range& oor){
00199 cout<<"Skipping out of range pulse: "<<*i_pulseID<<" on detector '"<<i_detector->first<<endl;
00200 continue;
00201 }
00202
00203
00204 PlotTPI(pulse,fPulseInfo);
00205 }
00206 }
00207 return 0;
00208 }
00209
00210
00211 std::string ExportPulse::PulseInfo_t::MakeTPIName()const{
00212 std::stringstream histname;
00213 histname << "Pulse_" << detname;
00214 histname << "_" << event;
00215 histname << "_" << pulseID;
00216 std::string hist=histname.str();
00217
00218
00219 modules::parser::ToCppValid(hist);
00220 return hist;
00221 }
00222
00223
00224 int ExportPulse::PlotTPI(const TPulseIsland* pulse, const PulseInfo_t& info){
00225
00226 std::string hist=info.MakeTPIName();
00227
00228 std::stringstream title;
00229 title << "Pulse " << info.pulseID;
00230 title << " from event " << info.event;
00231 title << " on detector " << info.detname;
00232 title << " (" << info.bankname<<")";
00233
00234
00235 if(Debug()){
00236 cout<<"Plotting "<<title.str()<<"' ["<<hist<<"]"<<endl;
00237 }
00238
00239 TH1F* fullPulse=MakeHistTPI(pulse,hist);
00240 fullPulse->SetDirectory(fTPIDirectory);
00241 fullPulse->SetTitle(title.str().c_str());
00242
00243 if(fUsePCF){
00244
00245 fullPulse->SetDirectory(0);
00246
00247
00248 THStack* stack=new THStack((hist+"_pulse_candidates").c_str(),title.str().c_str());
00249 stack->Add(fullPulse);
00250
00251 fPulseFinder->FindPulseCandidates(pulse);
00252 fPulseFinder->GetPulseCandidates(fSubPulses);
00253 for(PulseIslandList::const_iterator i_tpi=fSubPulses.begin(); i_tpi!=fSubPulses.end(); ++i_tpi){
00254 if((*i_tpi)->GetPulseLength() < 14) continue;
00255
00256 int shift=(*i_tpi)->GetTimeStamp()-pulse->GetTimeStamp();
00257 TH1F* sub_pulse=MakeHistTPI(*i_tpi,"sub_pulse",shift,pulse->GetPulseLength());
00258 sub_pulse->SetFillColor(kMagenta);
00259
00260
00261 fullPulse->Add(sub_pulse,-1);
00262 stack->Add(sub_pulse);
00263 }
00264
00265
00266 fTPIDirectory->Add(stack);
00267 }
00268
00269 return 0;
00270 }
00271
00272
00273 TH1F* ExportPulse::MakeHistTPI(const TPulseIsland* pulse, const std::string& name, int shift, int samples)const{
00274
00275 size_t num_samples = samples? samples: pulse->GetPulseLength();
00276 double min=0;
00277 double max= num_samples;
00278 TH1F* hPulse = new TH1F(name.c_str(), name.c_str(), num_samples,min,max);
00279 hPulse->SetDirectory(0);
00280
00281
00282 size_t bin=0;
00283 for ( size_t i=0;i <(size_t)pulse->GetPulseLength(); ++i) {
00284 bin=i+1+shift;
00285 hPulse->SetBinContent(bin, pulse->GetSamples().at(i));
00286 hPulse->SetBinError(bin, 0);
00287 }
00288 return hPulse;
00289 }
00290
00291
00292
00293 int ExportPulse::PlotTAP(const TAnalysedPulse* pulse, const PulseInfo_t& info)const{
00294 std::string hist=info.MakeTPIName();
00295 TH1F* tpi_hist=NULL;
00296 fTPIDirectory->GetObject(hist.c_str(),tpi_hist);
00297 pulse->Draw(tpi_hist);
00298 return 0;
00299 }
00300
00301
00302 PulseIslandList* ExportPulse::GetTPIsFromDetector(std::string bank){
00303 if(bank=="") bank=this->GetCurrentBankName();
00304 return &fGlobalData->fPulseIslandToChannelMap[bank];
00305 }
00306
00307
00308
00309 void ExportPulse::ShowGuidance()
00310 {
00311
00312 if(fGuidanceShown) return;
00313 fGuidanceShown=true;
00314 cout<<"Requests to draw a pulse should be formatted as event(pulse),"<<endl;
00315 cout<<" where event and pulse are the numbers of each event and pulse you wish to draw"<<endl;
00316
00317
00318 }
00319
00320
00321
00322 bool ExportPulse::ParseEventRequest(std::string input, std::vector<EventID_t>& event_list)
00323 {
00324 return ParseRequest(input,event_list,"event",0, GetTotalNumberOfEvents());
00325 }
00326
00327
00328
00329 bool ExportPulse::ParsePulseRequest(std::string input, std::vector<EventID_t>& list)
00330 {
00331 return ParseRequest(input,list,"pulse",0, GetTotalNumberOfEvents());
00332 }
00333
00334
00335
00336 bool ExportPulse::ParseRequest(std::string input, std::vector<EventID_t>& list, const std::string& type, Long64_t lower_limit, Long64_t upper_limit)
00337 {
00338
00339 modules::parser::RemoveWhitespace(input);
00340
00341
00342 if(modules::parser::IsNumber(input)){
00343 int event = modules::parser::GetNumber(input);
00344 if (event >=lower_limit && event < upper_limit ){
00345 list.push_back(event);
00346 } else {
00347 cout<<"Requested "<<type<<", "<<event<<" is out of range."<<endl;
00348 cout<<"Acceptable values are: ["<<lower_limit<<","<<upper_limit<<"[."<<endl;
00349 return false;
00350 }
00351 return true;
00352 }
00353
00354
00355
00356 return false;
00357 }
00358
00359
00360
00361 void ExportPulse::LoadPulsesRequestedByConfig(){
00362
00363
00364
00365 for(EventChannelPulseIDs_t::iterator i_channel=fRequestedByConfig.begin();
00366 i_channel!=fRequestedByConfig.end(); i_channel++){
00367 EventPulseIDList_t::iterator i_event=i_channel->second.find(GetCurrentEventNumber());
00368 if(i_event!=i_channel->second.end()){
00369 for(PulseIDList_t::const_iterator i_pulse=i_event->second.begin();
00370 i_pulse!=i_event->second.end(); i_pulse++){
00371 AddToExportList(i_channel->first,*i_pulse);
00372 }
00373 }
00374 }
00375
00376
00377 }
00378
00379
00380
00381 void ExportPulse::ClearPulsesToExport(){
00382 ChannelPulseIDs_t::iterator i_channel;
00383 for (i_channel=fTPIsToPlot.begin();i_channel!=fTPIsToPlot.end();i_channel++){
00384 i_channel->second.clear();
00385 }
00386 fTPIsToPlot.clear();
00387 fTAPsToPlot.clear();
00388 }
00389
00390 ALCAP_REGISTER_MODULE(ExportPulse,run_pulse_finder);