Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

AutoPIDMaker.cxx

Go to the documentation of this file.
00001 
00002 // $Id: AutoPIDMaker.cxx,v 1.11 2007/11/11 09:12:29 rhatcher Exp $
00003 //
00004 // FILL_IN: [Document your code!!]
00005 //
00006 // kordosky@hep.utexas.edu
00008 
00009 #include <cmath>
00010 
00011 #include "CalDetPID/AutoPIDMaker.h"
00012 #include "MessageService/MsgService.h"
00013 #include "MinosObjectMap/MomNavigator.h"
00014 #include "JobControl/JobCModuleRegistry.h" // For JOBMODULE macro
00015 #include "RawData/RawRunCommentBlock.h"
00016 #include "RawData/RawRecord.h"
00017 #include "RawData/RawHeader.h"
00018 #include "RawData/RawDaqHeader.h"
00019 #include "Conventions/Munits.h"
00020 #include "CalDetPID/CalDetParticleType.h"
00021 #include "CalDetPID/PIDFormulas.h"
00022 #include "CalDetPID/CalDetTOFRange.h"
00023 #include "CalDetPID/CalDetCERRange.h"
00024 #include "CalDetPID/CalDetCERTimeWin.h"
00025 #include "CalDetPID/CalDetOverlapWin.h"
00026 #include "CalDetPID/CalDetBeamMomentum.h"
00027 #include "Validity/VldTimeStamp.h"
00028 #include "Validity/VldContext.h"
00029 #include "Validity/VldRange.h"
00030 
00031 #include "DatabaseInterface/DbiCascader.h"
00032 #include "DatabaseInterface/DbiTableProxyRegistry.h"
00033 #include "DatabaseInterface/DbiWriter.h"
00034 #include "DatabaseInterface/DbiResultPtr.h"
00035 #include "DatabaseInterface/DbiValidityRec.h"
00036 
00037 
00038 //#include <string>
00039 //#include <map>
00040 #include <sstream>
00041 #include <cstdlib>
00042 #include <cmath>
00043 #include <vector>
00044 
00045 using namespace std;
00046 using namespace PIDFormulas;
00047 
00048 JOBMODULE(AutoPIDMaker, "AutoPIDMaker",
00049           "Constructs caldet pid tables from info in the run start block");
00050 CVSID("$Id: AutoPIDMaker.cxx,v 1.11 2007/11/11 09:12:29 rhatcher Exp $");
00051 //......................................................................
00052 
00053 //std::string AutoPIDMaker::ftestcomment="beam momentum (GeV) : 5.0\nUS Cerenkov pressure : 0.2\nDS Cerenkov pressure : 3.0";
00054 
00055 std::string AutoPIDMaker::ftestcomment="beam momentum (GeV) : +5.0(geV)\nUS Cerenkov pressure : 0.2\nDS Cerenkov pressure : 3.0";
00056 
00057 AutoPIDMaker::AutoPIDMaker() : 
00058      fdidrun(false), ftl(0), ftp(0), ftw(0),
00059      fbp(0), fuspr(0), fmidpr(0), fdspr(0)
00060 {
00061 //======================================================================
00062 // FILL_IN: [Document your code!!]
00063 //======================================================================
00064      const Registry& r = DefaultConfig();
00065      Config(r);
00066 
00067 }
00068 
00069 //......................................................................
00070 
00071 AutoPIDMaker::~AutoPIDMaker()
00072 {
00073 //======================================================================
00074 // FILL_IN: [Document your code!!]
00075 //======================================================================
00076 }
00077 
00078 //......................................................................
00079 
00080 void AutoPIDMaker::BeginJob()
00081 {
00082 //======================================================================
00083 // FILL_IN: [Document your code!!]
00084 //======================================================================
00085 
00086 
00087 }
00088 
00089 //......................................................................
00090 
00091 void AutoPIDMaker::EndJob()
00092 {
00093 //======================================================================
00094 // FILL_IN: [Document your code!!]
00095 //======================================================================
00096 }
00097 
00098 //......................................................................
00099 
00100 void AutoPIDMaker::BeginFile()
00101 {
00102 //======================================================================
00103 // FILL_IN: [Document your code!!]
00104 //======================================================================
00105 }
00106 
00107 //......................................................................
00108 
00109 void AutoPIDMaker::EndFile()
00110 {
00111 //======================================================================
00112 // FILL_IN: [Document your code!!]
00113 //======================================================================
00114 }
00115 
00116 //......................................................................
00117 
00118 void AutoPIDMaker::BeginRun()
00119 {
00120 //======================================================================
00121 // FILL_IN: [Document your code!!]
00122 //======================================================================
00123 
00124      fdidrun=false;
00125 
00126 }
00127 
00128 //......................................................................
00129 
00130 void AutoPIDMaker::EndRun()
00131 {
00132 //======================================================================
00133 // FILL_IN: [Document your code!!]
00134 //======================================================================
00135 }
00136 
00137 //......................................................................
00138 
00139 JobCResult AutoPIDMaker::Reco(MomNavigator* mom )
00140 {
00141 //======================================================================
00142 //
00143 // Calculate PID parameters and write to db
00144 //
00145 //======================================================================
00146 
00147      // if I've already seen this run then do nothing!
00148      if(fdidrun==true) return JobCResult::kPassed;
00149      
00150      // do a check on the data
00151      
00152      if(!SanityCheck()) {
00153           MSG("CalDetPID", Msg::kWarning)<<"SanityCheck() has failed. Will not calculate PID criteria for this run!"<<endl; 
00154           return JobCResult::kPassed;
00155      }
00156 
00157      // a list of particles and their masses, in gev
00158      const int npart = 5;
00159      CalDetParticleType::CalDetParticleType_t 
00160           particles[npart]={CalDetParticleType::kElectron,
00161                         CalDetParticleType::kMuon,
00162                         CalDetParticleType::kPion,
00163                         CalDetParticleType::kKaon,
00164                         CalDetParticleType::kProton};
00165      float m[npart] = {5E-4, 0.1057, 0.1396, 0.494, 0.938}; 
00166 
00167      // vectors to hold dbi table rows
00168      vector<CalDetTOFRange*> trv;
00169      vector<CalDetCERRange*> crv;
00170      vector<CalDetOverlapWin*> owv;
00171      vector<CalDetCERTimeWin*> ctv;
00172 
00173      // loop over particle types
00174      for(int i=0; i<npart; i++){
00175 
00176           // TOF CALCULATION
00177           const float tof_lim=4096.0; // should be settable?
00178           
00179           // ftp= Mean for electrons (by convention)
00180           const float tof_mean=TimeOfFlight(m[i],fbp,ftl) 
00181                + ftp-TimeOfFlight(m[0], fbp, ftl);
00182           float w = ftofsigma;
00183           float t = 0.0;
00184           if(particles[i]==CalDetParticleType::kProton && fcorrproton!=0){
00185              // correct tof for low energy protons
00186              w = CorrProtonWidth(fbp, w);
00187              t = CorrProtonTOF(fbp);
00188           }
00189           trv.push_back( new CalDetTOFRange( particles[i],
00190                                          -tof_lim, tof_lim,
00191                                         -tof_lim, tof_lim,
00192                                         -tof_lim, tof_lim,
00193                                         (tof_mean+t)-w*ftw, 
00194                                         (tof_mean+t)+w*ftw,
00195                                         -2*tof_lim, 2*tof_lim) );
00196      
00197           // CER CALCULATION
00198           const float n_minus_one_C02 = 4.1E-4;
00199           // dont care values will pass everything!
00200           const float dont_care_low=-1.0; 
00201           const float dont_care_high=1E5;
00202           // zero values will require the signal to be zero!
00203           const float zero_low=-1.0;
00204           const float zero_high=1.0;
00205           // cer timing window
00206           const float bigctw=1E5;
00207 
00208           //uscer
00209           float uslow=dont_care_low;
00210           float ushigh=dont_care_high;
00211           float usctwlow=-bigctw;
00212           float usctwhigh=bigctw;
00213           if(fuspr==-1.0){// do not use uscer
00214           }
00215           else if(CERThreshold(m[i],fbp,n_minus_one_C02)<fuspr){
00216                // this species over threshold for uscer
00217                uslow=fuscerlow;
00218                ushigh=fuscerhigh;
00219                usctwlow=fusctwlow;
00220                usctwhigh=fusctwhigh;
00221           }
00222           else {
00223                // this species under threshold for uscer
00224                // require no signals for this particle
00225                uslow=zero_low;
00226                ushigh=zero_high;
00227           }
00228 
00229           //midcer
00230           float midlow=dont_care_low;
00231           float midhigh=dont_care_high;
00232           float midctwlow=-bigctw;
00233           float midctwhigh=bigctw;
00234           if(fmidpr==-1.0){// do not use midcer
00235           }
00236           else if(CERThreshold(m[i],fbp,n_minus_one_C02)<fmidpr){
00237                // this species over threshold for midcer
00238                midlow=fmidcerlow;
00239                midhigh=fmidcerhigh;
00240                midctwlow=fmidctwlow;
00241                midctwhigh=fmidctwhigh;
00242           }
00243           else {
00244                // this species under threshold for midcer
00245                // require no signals for this particle
00246                midlow=zero_low;
00247                midhigh=zero_high;
00248           }
00249 
00250           //dscer
00251           float dslow=dont_care_low;
00252           float dshigh=dont_care_high;
00253           float dsctwlow=-bigctw;
00254           float dsctwhigh=bigctw;
00255           if(fdspr==-1.0){// do not use dscer
00256           }
00257           else if(CERThreshold(m[i],fbp,n_minus_one_C02)<fdspr){
00258                // this species over threshold for dscer
00259                dslow=fdscerlow;
00260                dshigh=fdscerhigh;
00261                dsctwlow=fdsctwlow;
00262                dsctwhigh=fdsctwhigh;
00263           }
00264           else {
00265                // this species under threshold for dscer
00266                // require no signals for this particle
00267                dslow=zero_low;
00268                dshigh=zero_high;
00269           }
00270           
00271           // store the cerrange table row
00272           crv.push_back( new CalDetCERRange(particles[i],
00273                                             midlow, midhigh,
00274                                             dslow, dshigh,
00275                                             uslow, ushigh) );
00276           
00277           // store cer timing window table row
00278           ctv.push_back( new CalDetCERTimeWin(particles[i],
00279                                               midctwlow, midctwhigh,
00280                                               dsctwlow, dsctwhigh,
00281                                               usctwlow, usctwhigh) );
00282 
00283           // construct overlap window
00284           float ollow=-500.0;
00285           float olhigh=500.0;
00286           if(particles[i]==CalDetParticleType::kElectron){
00287                ollow=felecollow;
00288                olhigh=felecolhigh;
00289           }
00290           else {
00291                ollow=fhadollow;
00292                olhigh=fhadolhigh;
00293           }
00294           owv.push_back( new CalDetOverlapWin(particles[i],ollow,olhigh) );
00295                          
00296      }
00297 
00298      // ok, now can write out to the db
00299      bool db_ok=true;
00300      // if we are testing, then require that we write to a temp table
00301      if(ftest!=0) fwritetemp=1;
00302      // the job can choose to write to a temp table
00303      if(fwritetemp!=0){
00304           MSG("CalDetPID", Msg::kDebug)<<"Creating temp tables."<<endl;
00305           // then we should write to a temp table
00306           DbiCascader& cascader 
00307                = DbiTableProxyRegistry::Instance().GetCascader();
00308           // beam momentum
00309           Int_t bp_no = 
00310                cascader.CreateTemporaryTable("CALDETBEAMMOMENTUM",
00311                                              CalDetBeamMomentum::GetTableDesc());
00312           if(bp_no<0){
00313                MSG("CalDetPID", Msg::kError)
00314                     <<"Trying to write a temp table but "
00315                     <<"no database will accept it!"<<endl;
00316                db_ok=false;
00317           }
00318           // tof range
00319           Int_t tr_no = 
00320                cascader.CreateTemporaryTable("CALDETTOFRANGE",
00321                                              CalDetTOFRange::GetTableDesc());
00322           if(tr_no<0){
00323                MSG("CalDetPID", Msg::kError)
00324                     <<"Trying to write a temp table but "
00325                     <<"no database will accept it!"<<endl;
00326                db_ok=false;
00327           }
00328           // cer range
00329           Int_t cr_no = 
00330                cascader.CreateTemporaryTable("CALDETCERRANGE",
00331                                              CalDetCERRange::GetTableDesc());
00332           if(cr_no<0){
00333                MSG("CalDetPID", Msg::kError)
00334                     <<"Trying to write a temp table but "
00335                     <<"no database will accept it!"<<endl;
00336                db_ok=false;
00337           }
00338           // cer win
00339           Int_t cw_no = 
00340                cascader.CreateTemporaryTable("CALDETCERTIMEWIN",
00341                                              CalDetCERTimeWin::GetTableDesc());
00342           if(cw_no<0){
00343                MSG("CalDetPID", Msg::kError)
00344                     <<"Trying to write a temp table but "
00345                     <<"no database will accept it!"<<endl;
00346                db_ok=false;
00347           }
00348           // overlap win
00349           Int_t ow_no = 
00350                cascader.CreateTemporaryTable("CALDETOVERLAPWIN",
00351                                              CalDetOverlapWin::GetTableDesc());
00352           if(ow_no<0){
00353                MSG("CalDetPID", Msg::kError)
00354                     <<"Trying to write a temp table but "
00355                     <<"no database will accept it!"<<endl;
00356                db_ok=false;
00357           }
00358           
00359      }
00360      // do the actual writing
00361      // get the run start time from the raw header
00362      MSG("CalDetPID", Msg::kDebug)<<"Record business."<<endl;
00363      VldTimeStamp start;
00364      Int_t run = 0;
00365      const RawRecord* rr = 
00366           dynamic_cast<const RawRecord*>(mom->GetFragment("RawRecord"));
00367      if(!rr){
00368           MSG("CalDetPID", Msg::kError)
00369                <<"Did not find a RawRecord. Will not write any tables."<<endl;
00370           db_ok=false;
00371      }
00372      else{
00373           const RawDaqHeader* rh = 
00374                dynamic_cast<const RawDaqHeader*>(rr->GetRawHeader());
00375           if(rh) {
00376                start=rh->GetVldContext().GetTimeStamp();
00377                run = rh->GetRun();
00378           }
00379           else{
00380                MSG("CalDetPID", Msg::kError)
00381                     <<"Did not find a RawHeader. "
00382                     <<"Will not write any tables."<<endl;
00383                db_ok=false;
00384           }
00385      }
00386      MSG("CalDetPID", Msg::kDebug)<<"DB ok. Trying to write."<<endl;
00387      if(db_ok){
00388           // if the db is ok at this point we can try to write
00389           const Detector::Detector_t det=Detector::kCalDet;
00390           const SimFlag::SimFlag_t sim=SimFlag::kData;
00391           const int aggno=-1;
00392           const Dbi::Task task=0;
00393           const VldTimeStamp create=start;
00394           // ending vld time = start + offset
00395           // the plan is subsequent runs within the offset period
00396           // will overlay and overide this one
00397           // Thanks dbi!
00398           const time_t end_offset_sec=12*3600; // 12 hour validity time
00399           VldTimeStamp end=start; end.Add(VldTimeStamp(end_offset_sec,0));
00400           const VldRange range(det,sim,start,end,"AutoPIDMaker");
00401           
00402           // beam momentum
00403           CalDetBeamMomentum cdbm(run, fbp);
00404           DbiWriter<CalDetBeamMomentum> w_bp(range,aggno,task,create);
00405           MSG("CalDetPID", Msg::kInfo)<<"Writing row:\n"
00406                                       << cdbm<<endl;
00407 
00408           w_bp<<cdbm;
00409           w_bp.Close();
00410 
00411           // the multiple row writes
00412           DbiWriter<CalDetTOFRange> w_tr(range,aggno,task,create);
00413           DbiWriter<CalDetCERRange> w_cr(range,aggno,task,create);
00414           DbiWriter<CalDetCERTimeWin> w_ct(range,aggno,task,create);
00415           DbiWriter<CalDetOverlapWin> w_ow(range,aggno,task,create);
00416           MSG("CalDetPID", Msg::kDebug)<<"Looping to write rows."<<endl;
00417           for(int i=0; i<npart; i++){
00418                // trv, crv, owv, ctv
00419                // tof range
00420                MSG("CalDetPID", Msg::kInfo)<<"Writing row:\n"
00421                                             << *(trv[i])<<endl;
00422                w_tr<<*(trv[i]);
00423                // cer range
00424                MSG("CalDetPID", Msg::kInfo)<<"Writing row:\n"
00425                                             << *(crv[i])<<endl;
00426                w_cr<<*(crv[i]);
00427                // cer window
00428                MSG("CalDetPID", Msg::kInfo)<<"Writing row:\n"
00429                                             << *(ctv[i])<<endl;
00430                w_ct<<*(ctv[i]);
00431                // overlap window
00432                MSG("CalDetPID", Msg::kInfo)<<"Writing row:\n"
00433                                             << *(owv[i])<<endl;
00434                w_ow<<*(owv[i]);
00435           }
00436           // close writers
00437           w_tr.Close();
00438           w_cr.Close();
00439           w_ct.Close();
00440           w_ow.Close();
00441           
00442      }
00443 
00444      MSG("CalDetPID", Msg::kDebug)<<"Now deleting table rows."<<endl;
00445      // delete table row entries from vectors
00446      for(int i=0; i<npart; i++){
00447           if(trv[i]!=0) {delete trv[i]; trv[i]=0;}
00448           if(crv[i]!=0) {delete crv[i]; crv[i]=0;}
00449           if(ctv[i]!=0) {delete ctv[i]; ctv[i]=0;}
00450           if(owv[i]!=0) {delete owv[i]; owv[i]=0;}
00451      }
00452 
00453      // all done
00454      fdidrun=true;
00455 
00456      return JobCResult::kPassed; // kNoDecision, kFailed, etc.
00457 }
00458 
00459 //......................................................................
00460 
00461 JobCResult AutoPIDMaker::Get(MomNavigator* mom)
00462 {
00463 //======================================================================
00464 // Looks for a run comment block
00465 // Reads the block and extracts member variables
00466 //======================================================================
00467      
00468      // if I've already seen this run then do nothing!
00469      if(fdidrun==true) return JobCResult::kPassed;
00470   
00471      const RawRecord* rr = 
00472           dynamic_cast<const RawRecord*>(mom->GetFragment("RawRecord"));
00473      
00474      if(!rr){
00475           MSG("CalDetPID", Msg::kInfo)
00476                <<"Did not find a RawRecord. Doing nothing."<<endl;
00477           return JobCResult::kFailed;
00478      }
00479      
00480      const RawRunCommentBlock* rcb = 
00481           dynamic_cast<const RawRunCommentBlock*>(
00482                rr->FindRawBlock("RawRunCommentBlock"));
00483      if(!rcb){
00484           MSG("CalDetPID", Msg::kDebug)
00485                <<"Could not find a RawRunCommentBlock!\n"
00486                <<"Cannot compute PID parameters until I do!"
00487                <<endl;
00488           return JobCResult::kFailed;
00489      }
00490      
00491      // got a good runcommentblock
00492      MSG("CalDetPID", Msg::kInfo)
00493           <<"Got the following RawRunCommentBlock:\n"<<*rcb<<endl;
00494      string s;
00495      if(ftest==0){
00496           // copy run comment into string
00497           s=rcb->GetRunComment();
00498           MSG("CalDetPID", Msg::kInfo)<<"The comment was: \n"<<s<<endl;
00499      }
00500      else {
00501           s=ftestcomment;
00502           MSG("CalDetPID", Msg::kInfo)<<"Testing with the comment:\n"
00503                                       <<s<<endl;
00504      }
00505      // convert run comment into a map
00506      const int slen = s.length();
00507      // if the run comment doesn't end with a newline then add one
00508      if(s[slen-1]!='\n') s+='\n';
00509      map<string,string> ms;
00510      RCtoMap(s,ms);
00511 
00512      // dig through the map to pull out relevant values
00513      // try to reject crappy entries
00514      
00515      bool ok=true;
00516      double dval=0.0;
00517      
00518      if(FindDouble(ms,"beam momentum (GeV) ", dval)) fbp=dval;
00519      else ok&=false;
00520 
00521      if(FindDouble(ms,"US Cerenkov pressure ",dval)) fuspr=dval;
00522      else ok&=false;
00523 
00524      if(FindDouble(ms,"DS Cerenkov pressure ",dval)) fdspr=dval;
00525      else ok&=false;
00526      
00527 //     if(FindDouble(ms,"MIDCER pressure (atm) ",dval)) fmidpr=dval;
00528 //     else ok&=false;
00529 
00530      // all done!
00531 //     fdidrun=true;
00532      return JobCResult::kPassed; // kNoDecision, kFailed, etc.
00533 }
00534 
00535 //......................................................................
00536 
00537 JobCResult AutoPIDMaker::Ana(const MomNavigator* /* mom */)
00538 {
00539 //======================================================================
00540 // FILL_IN: [Document your code!!]
00541 //======================================================================
00542   return JobCResult::kPassed; // kNoDecision, kFailed, etc.
00543 }
00544 
00545 //......................................................................
00546 
00547 const Registry& AutoPIDMaker::DefaultConfig() const
00548 {
00549 //======================================================================
00550 // Supply the default configuration for the module
00551 //======================================================================
00552   static Registry r; // Default configuration for module
00553 
00554   // Set name of config
00555   std::string name = this->GetName();
00556   name += ".config.default";
00557   r.SetName(name.c_str());
00558 
00559   // Set values in configuration
00560   r.UnLockValues();
00561   r.Set("writetemp", 1);
00562   r.Set("toflength", 9.11);
00563   r.Set("tofped",    417.2);
00564   r.Set("tofwidth",  3.0);
00565   r.Set("beamp",     0.0);
00566   r.Set("usceratm",  -1.0);
00567   r.Set("midceratm", -1.0);
00568   r.Set("dsceratm",  -1.0);
00569 
00570   // tof sigma
00571   r.Set("tofsigma", 2.5);
00572 
00573   // cer selection ranges
00574   r.Set("uscerlow", 50.0);
00575   r.Set("uscerhigh", 1.6E4);
00576   r.Set("midcerlow", 50.0);
00577   r.Set("midcerhigh", 1.6E4);
00578   r.Set("dscerlow", 50.0);
00579   r.Set("dscerhigh", 1.6E4);
00580 
00581   // cer timing window
00582   r.Set("usctwhigh", -63.0);
00583   r.Set("usctwlow", -103.0);
00584   r.Set("midctwhigh", -1E5);
00585   r.Set("midctwlow", 1E5);
00586   r.Set("dsctwhigh", 14.0);
00587   r.Set("dsctwlow", -26.0);
00588 
00589   // overlap ranges
00590   r.Set("elecollow", -80.0);
00591   r.Set("elecolhigh", 0.0);
00592   r.Set("hadollow", -80.0);
00593   r.Set("hadolhigh", 160.0);
00594 
00595   // for testing
00596   r.Set("test", 0);
00597 
00598   // low energy proton tof correction
00599   r.Set("corrproton", 1);
00600 
00601 //  r.Set("testcomment","");
00602   r.LockValues();
00603 
00604   return r;
00605 }
00606 
00607 //......................................................................
00608 
00609 void AutoPIDMaker::Config(const Registry& r)
00610 {
00611 //======================================================================
00612 // Configure the module given the Registry r
00613 //======================================================================
00614   double tmpd;
00615   int tmpi;
00616 
00617   if (r.Get("writetemp",tmpi)) { fwritetemp = tmpi; }
00618 
00619   if (r.Get("toflength",tmpd)) { ftl = tmpd; }
00620   if (r.Get("tofped",tmpd)) { ftp = tmpd; }
00621   if (r.Get("tofwidth",tmpd)) { ftw = tmpd; }
00622   if (r.Get("beamp",tmpd)) { fbp = tmpd; }
00623   if (r.Get("usceratm",tmpd)) { fuspr = tmpd; }
00624   if (r.Get("midceratm",tmpd)) { fmidpr = tmpd; }
00625   if (r.Get("dsceratm",tmpd)) { fdspr = tmpd; }
00626 
00627   // tof sigma
00628   if (r.Get("tofsigma",tmpd)) { ftofsigma = tmpd; }
00629 
00630   // cer selection ranges
00631   if (r.Get("uscerlow",tmpd)) { fuscerlow = tmpd; }
00632   if (r.Get("uscerhigh",tmpd)) { fuscerhigh = tmpd; }
00633   if (r.Get("midcerlow",tmpd)) { fmidcerlow = tmpd; }
00634   if (r.Get("midcerhigh",tmpd)) { fmidcerhigh = tmpd; }
00635   if (r.Get("dscerlow",tmpd)) { fdscerlow = tmpd; }
00636   if (r.Get("dscerhigh",tmpd)) { fdscerhigh = tmpd; }
00637 
00638   // cer timing window
00639   if (r.Get("usctwlow",tmpd)) { fusctwlow = tmpd; }
00640   if (r.Get("usctwhigh",tmpd)) { fusctwhigh = tmpd; }
00641   if (r.Get("midctwlow",tmpd)) { fmidctwlow = tmpd; }
00642   if (r.Get("midctwhigh",tmpd)) { fmidctwhigh = tmpd; }
00643   if (r.Get("dsctwlow",tmpd)) { fdsctwlow = tmpd; }
00644   if (r.Get("dsctwhigh",tmpd)) { fdsctwhigh = tmpd; }
00645 
00646   // overlap window
00647   if (r.Get("elecollow",tmpd)) { felecollow = tmpd; }
00648   if (r.Get("elecolhigh",tmpd)) { felecolhigh = tmpd; }
00649   if (r.Get("hadollow",tmpd)) { fhadollow = tmpd; }
00650   if (r.Get("hadolhigh",tmpd)) { fhadolhigh = tmpd; }
00651 
00652   // for testing
00653   if (r.Get("test", tmpi)) { ftest=tmpi;}
00654 
00655   // low energy proton tof correction
00656   if (r.Get("corrproton", tmpi)) {fcorrproton=tmpi;}
00657 
00658   
00659 
00660 /*
00661   const char* tmpc;
00662   if (r.Get("testcomment", tmpc)) {
00663        MSG("CalDetPID", Msg::kDebug)<<"Got testcomment: \n"<<tmpc<<endl;
00664        ftestcomment=tmpc;
00665   }
00666 */
00667 
00668 }
00669 
00670 //......................................................................
00671 
00672 void AutoPIDMaker::Help()
00673 {
00674 //======================================================================
00675 // FILL_IN: [Document your code!!]
00676 //======================================================================
00677 }
00678 
00680 
00681 void AutoPIDMaker::RCtoMap(std::string& s, 
00682                            std::map<std::string, std::string>& ms) const
00683 {
00684      // converts the run comment string into a map
00685      // the key is the bit left of the : and the value is the bit to the right
00686      std::istringstream ss(s);
00687      while(!ss.eof()){
00688           char lbuf[256]={'0'};
00689           char rbuf[256]={'0'};
00690           ss.getline(lbuf, 256, ':');
00691           ss.getline(rbuf, 256);
00692           if(ss.eof()) break;
00693           ms.insert(pair<std::string,std::string>(std::string(lbuf), 
00694                                                   std::string(rbuf)));
00695      }
00696      return;
00697 }
00698 
00699 bool AutoPIDMaker::ExtractDouble(std::string& v, double& val) const
00700 {
00701    // this algorithm was bad when people typed "+1 GEV" or some such
00702    // try to fix it by stripping out anything that is not a number
00703    // or .+-
00704    int found_dig=0;
00705    string vstrip;
00706    for(unsigned int i=0; i<v.length(); i++){
00707       if( (isdigit(v[i]))||(v[i]=='.')||(v[i]=='+')||(v[i]=='-') ){
00708          // accept these
00709          vstrip+=v[i];
00710          if(isdigit(v[i])) found_dig++;
00711       } 
00712 
00713    }
00714    // checks if s can be converted to a number and extracts it if so
00715 
00716    // the checking bit
00717    if(vstrip.length()==0) return false;// nothing at all
00718    if(found_dig==0) return false; // no numbers
00719    
00720 /*
00721    bool ok=true;
00722    for(unsigned int i=0; i<vstrip.length(); i++){
00723       if(!( (isdigit(vstrip[i]))
00724             ||(isspace(vstrip[i]))
00725             ||(vstrip[i]=='.')
00726             ||(vstrip[i]=='+')
00727             ||(vstrip[i]=='-')
00728             )){ok=false; break;}
00729    }
00730      
00731    if(!ok) return false;
00732 */
00733 
00734    // looks like a number so extract it
00735    istringstream in(vstrip);
00736    in>>val;
00737 
00738    return true;
00739 }
00740 
00741 bool AutoPIDMaker::FindDouble(std::map<std::string, std::string>& ms,
00742                               const char* k, double& value) const 
00743 {
00744 
00745      double dval;
00746      typedef map<string,string>::iterator MIT;
00747      MIT it=ms.begin();
00748      string key(k);
00749      if(key.length()==0) return false;
00750      
00751      it = ms.find(key);
00752      if(it!=ms.end()){ 
00753           if(ExtractDouble(it->second, dval)){
00754                value=dval;
00755                return true;
00756           }
00757           else{
00758                MSG("CalDetPID", Msg::kError)
00759                     <<"Failed to extract a double from \""<<it->second
00760                     <<"\"!"<<endl;
00761                return false;
00762           }
00763      }
00764      else{
00765           MSG("CalDetPID", Msg::kError)
00766                <<"Could not find a value for the key \""<<key<<"\" !"<<endl;
00767           return false;
00768      }
00769 }
00770 
00771 bool AutoPIDMaker::SanityCheck() const
00772 {
00773      // does a simple sanity check on the member data to decide if 
00774      // it is reasonable to try and make pid tables from it
00775      bool ok=true;
00776      // check for reasonable beam momentum
00777      if( !(abs(fbp)>0.05 && abs(fbp)<11.0) ) ok&=false;
00778      // check tof baseline
00779      if( !(ftl>0.0 && ftl<13.0) ) ok&=false;
00780      // check tof width... just needs to be > 0
00781      if( !(ftw>0.0) ) ok&=false;
00782      // check tof pedestal
00783      if( !(abs(ftp)<4096) ) ok&=false;
00784      // check if cer pressure is in the reasonable range
00785      // or, if pressure==-1 then that channel will be considered unused
00786      // it will not be used in selections and any signal will be valid
00787      // for any type of particle
00788      if( !((fuspr>0.0 && fuspr<5.0) || fuspr==-1.0) ) ok&=false;
00789      if( !((fmidpr>0.0 && fmidpr<5.0) || fmidpr==-1.0) ) ok&=false;
00790      if( !((fdspr>0.0 && fdspr<5.0) || fdspr==-1.0) ) ok&=false;
00791 
00792      // all done
00793      return ok;
00794 }
00795 
00796 float AutoPIDMaker::CorrProtonWidth(float p, float w) const
00797 {
00798    if(p<0.8) p=0.8; // apply correction for 0.8 below 0.8
00799    float corw = 2.91 + 13.56/pow(p,4);
00800    if(corw<w) corw=w; // use the width w as a minimum
00801    return corw;
00802 }
00803 
00804 float AutoPIDMaker::CorrProtonTOF(float p) const
00805 {
00806    float tc=0;
00807    if(! (fabs(p)>1.2 ) ) tc = -3.6 + 11.15/pow(p,4);
00808    return tc;
00809 }

Generated on Mon Jun 16 14:56:30 2008 for loon by  doxygen 1.3.9.1