//----------------------------------------------------------- // File and Version Information: // $Id$ // // Description: // Evaluation of combined FOPI PID information // // // // Environment: // Software developed for GEM-TPC detector in FOPI. // // Author List: // Felix Boehmer TUM (original author) // // //----------------------------------------------------------- #include "FopiPidHub.h" #include "FopiPidProb.h" #include "FopiPidProbSet.h" #include "TList.h" #include "TKey.h" #include "TFile.h" #include "TGraphErrors.h" #include #include #include #include #include ClassImp(FopiPidHub) ClassImp(FopiPidMomWindow) FopiPidMomWindow::FopiPidMomWindow() : isRange(false), isSharp(false), momLow(0.), momHigh(0.), momSharp(0.) {;} FopiPidMomWindow::FopiPidMomWindow(double low, double high) : isRange(true), isSharp(false), momLow(low), momHigh(high), momSharp(0.) {;} FopiPidMomWindow::FopiPidMomWindow(double sharp) : isRange(false), isSharp(true), momLow(0.), momHigh(0.), momSharp(sharp) {;} FopiPidMomWindow& FopiPidMomWindow::operator=(const FopiPidMomWindow& other) { if(this == &other) return *this; isRange = other.isRange; isSharp = other.isSharp; momLow = other.momLow; momHigh = other.momHigh; momSharp = other.momSharp; return *this; } bool FopiPidMomWindow::operator==(const FopiPidMomWindow& other) const { if(isRange && other.isRange) { double dl = std::fabs(momLow - other.momLow); double dh = std::fabs(momHigh - other.momHigh); if(dl+dh < 1.e-5) return true; else return false; } else if(isRange && other.isSharp) { if((other.momSharp >= momLow) && (other.momSharp <= momHigh)) return true; else return false; } else if(isSharp && other.isRange) { if((momSharp >= other.momLow) && (momSharp <= other.momHigh)) return true; else return false; } else return false; } bool FopiPidMomWindow::operator<(const FopiPidMomWindow& other) const { if(isRange && other.isRange) { return momLow < other.momLow; } else if(isRange && other.isSharp) { return momHigh < other.momSharp; } else if(isSharp && other.isRange) { return momSharp < other.momLow; } else return momLow < other.momLow; } //IMPLEMENTATIONS FOR FOPIPIDHUB --------------------------------------------------- FopiPidHub::FopiPidHub() : fVerbose(false), fInit(false), fFractionsMC("") { buildBookMap(); } void FopiPidHub::setDetProbFile(const TString& det, const TString& file) { fFileMap[det]=file; } int FopiPidHub::setCalibrationFile(const TString& det, const TString& file, const TString& pikey, const TString& protkey, int runLow, int runHigh) { assert(runLow(pikey,protkey); fCalibIOMap[det] = file; fCalibRangeMap[det] = std::pair(runLow,runHigh); return 0; } int FopiPidHub::setUseMCFractions(const TString& file) { fFractionsMC = file; } TString FopiPidHub::getDetProbFile(const TString& det) const { std::map::const_iterator it; it = fFileMap.find(det); if(it==fFileMap.end()) return TString(""); else return it->second; } //TODO close memory leaks with TFile pointers. // int FopiPidHub::init() { //init maps from probability input std::map::const_iterator fit; for(fit=fFileMap.begin(); fit!=fFileMap.end(); fit++) { TString detName = fit->first; TString fileName = fit->second; if(fileName.Length() > 1) { TFile* ifile = new TFile(fileName,"read"); if(ifile->IsZombie()) { std::cerr<<"FopiPidHub::init() Could not read file for detector " <GetListOfKeys(); for(unsigned int k=0; kGetEntries(); k++) { TKey* ikey = (TKey*) keys->At(k); TString cname = ikey->GetClassName(); //ADD THE SET: if(cname.EqualTo("FopiPidProbSet")) { TString name = ikey->GetName(); FopiPidProbSet* iset = (FopiPidProbSet*) ifile->Get(name); if(iset == NULL) { std::cerr<<"FopiPidHub::init() Got invalid ProbSet ... abort init" <getMomWindow(mLow,mHigh); FopiPidMomWindow window(mLow,mHigh); std::map* thismap = fBookMap[detName]; std::pair::iterator,bool> test; test = thismap->insert(std::pair(window,iset)); //check if insertion was successful: if(test.second==false) { std::cerr<<"FopiPidHub::init() Could not insert ProbSet!" <IsZombie()) std::cout<<"FopiPidHub::init() Could not open MC fraction input file" <GetListOfKeys(); for(unsigned int k=0; kGetEntries(); k++) { TKey* ikey = (TKey*) fracKeys->At(k); TString cname = ikey->GetClassName(); //ADD THE SET: if(cname.EqualTo("FopiPidFractionSet")) { TString name = ikey->GetName(); FopiPidFractionSet* iset = (FopiPidFractionSet*) fracFile->Get(name.Data()); if(iset == NULL) { std::cerr<<"FopiPidHub::init() Got invalid FractionSet ... abort init" <Close(); delete fracFile; return 1; } double mLow, mHigh; iset->getMomWindow(mLow,mHigh); FopiPidMomWindow window(mLow,mHigh); std::pair::iterator,bool> test; std::pair ins(window,FopiPidFractionSet(*iset)); test = fFracMCMap.insert(ins); //check if insertion was successful: if(test.second==false) { std::cerr<<"FopiPidHub::init() Could not insert FractionSet!" <Close(); delete fracFile; return 1; } } } fracFile->Close(); delete fracFile; } fInit = true; return 0; } double FopiPidHub::getFraction(const TString& part, double mom) const { if(!fInit) { std::cout<<"FopiPidHub::getFraction() I am not initialized! Returning -1." <::const_iterator mcit; mcit = fFracMCMap.find(win); if(mcit==fFracMCMap.end()) { std::cout<<"FopiPidHub::getFraction() Could not find MC fraction for mom "<second.getFraction(part); if(mcfrac < 0.) { std::cout<<"FopiPidHub::getFraction() Lookup failed for particle " <* >::const_iterator meh; meh = fBookMap.find("tpc"); std::map* tpcMap; if(meh == fBookMap.end()) return -1.; else tpcMap = meh->second; std::map::const_iterator it; it = tpcMap->find(win); if(it==tpcMap->end()) return -1.; else return it->second->getFraction(part); } } double FopiPidHub::getFracLikelihood(const TString& part, double mom, const FopiPidInfo& data, bool weighted) const { if(!fInit) { std::cout<<"FopiPidHub::getFracLikelihood() I am not initialized! Returning -1." < > lis; //get likelihoods; data is calibrated if calibration data is present int stat = this->getLikelihoodMap(mom, data, lis); if(stat>0) { std::cout<<"FopiPidHub::getFracLikelihood() Failed to get internal " <<"likelihood mapping; Returning -1."< > likes; //partname <- list of det likelihoods std::map weights; //partname <- weight std::map >::const_iterator detit; //loop over single detector likelihoods for(detit=lis.begin(); detit!=lis.end(); detit++) { std::map::const_iterator partit; if(fVerbose) std::cout<<"FopiPidHub::getFracLikelihood() Looking up'" <first.Data()<<"' ..."<second.begin(); partit!=detit->second.end(); partit++) { //make entry in the weightmap if non-existent if(!weights.count(partit->first)) { if(weighted) { if(fVerbose) std::cout<<"FopiPidHub::getFracLikelihood() Making entry in weightmap for '" <first<<"': " << this->getFraction(partit->first,mom)<first] = this->getFraction(partit->first,mom); } else weights[partit->first] = 1.; } likes[partit->first].push_back(partit->second); if(fVerbose) std::cout<<"FopiPidHub::getFracLikelihood() Setting lh for '" <first<<"': "<second<::const_iterator it; for(it=weights.begin(); it!=weights.end(); it++) { double weight = it->second; //for clarity double partlike = weight; std::vector partlikes = likes[it->first]; for(unsigned int il=0; ilfirst.EqualTo(part)) nay += partlike; else yea += partlike; } if(fVerbose) std::cout<<"FopiPidHub::getFracLikelihood() Yea: "<getFracLikelihood(part, contestant, TString("none"), mom, data, weighted); } //get fractional likelihood of hypothesis part versus hypotheses contestant 1 & 2 double FopiPidHub::getFracLikelihood(const TString& part, const TString& contestant1, const TString& contestant2, double mom, const FopiPidInfo& data, bool weighted) const { if(!fInit) { std::cout<<"FopiPidHub::getFracLikelihood() I am not initialized! " <<"Returning -1." < > lis; //get likelihoods; data is calibrated if calibration data is present int stat = this->getLikelihoodMap(mom, data, lis); if(stat>0) { std::cout<<"FopiPidHub::getFracLikelihood() Failed to get internal " <<"likelihood mapping; Returning -1."< partlist; partlist.push_back(part); if(!contestant1.EqualTo("none")) partlist.push_back(contestant1); if(!contestant2.EqualTo("none")) partlist.push_back(contestant2); std::map > likes; //partname <- list of det likelihoods std::map weights; //partname <- weight std::map >::const_iterator detit; //loop over single detector likelihoods for(detit=lis.begin(); detit!=lis.end(); detit++) { std::map::const_iterator partit; if(fVerbose) std::cout<<"FopiPidHub::getFracLikelihood() Looking up'" <first.Data()<<"' ..."<second.find(thispart); if(partit == detit->second.end()) continue; //make entry in the weightmap if non-existent if(!weights.count(thispart)) { if(weighted) { if(fVerbose) std::cout<<"FopiPidHub::getFracLikelihood() Making entry in weightmap for '" <getFraction(thispart,mom)<getFraction(thispart,mom); } else weights[thispart] = 1.; } likes[thispart].push_back(partit->second); if(fVerbose) std::cout<<"FopiPidHub::getFracLikelihood() Setting lh for '" <second< likelihoods = likes[(partlist[ipart])]; double likelihood = weight; for(unsigned int il=0; il::const_iterator it; // for(it=weights.begin(); it!=weights.end(); it++) { // double weight = it->second; //for clarity // double partlike = weight; // std::vector partlikes = likes[it->first]; // for(unsigned int il=0; ilfirst.EqualTo(part)) // nay += partlike; // else // yea += partlike; // } if(fVerbose) std::cout<<"FopiPidHub::getFracLikelihood() Yea: "< > //contains only valid entries (detectors, particles) //for TPC and CDC kaon likelihoods are treated equal to the pion/electron peak //if no kaon fit is available. However, when using TPC dEdx fractions, the weighted //kaon likelihhods will be zero. //Validity ranges of each FopiPidProbSet are checked. If data lies outside, //the returned likelihoods will be zero. int FopiPidHub::getLikelihoodMap(double mom, const FopiPidInfo& uc_data, std::map >& mapret) const{ mapret.clear(); //CALIBRATE DATA FopiPidInfo data = getCalibratedData(uc_data); if(fVerbose) std::cout<<"FopiPidHub::getLikeliHoodMap()"< dets; if(data.hasTpc()) dets.push_back("tpc"); if(data.hasCdc()) dets.push_back("cdc"); if(data.hasBar()) dets.push_back("bar"); if(data.hasRpc()) dets.push_back("rpc"); //not using the boolean information: std::map* partmap = makePartMap("pion"); if(partmap==NULL) { std::cerr<<"FopiPidHub::getLikelihoodMap() INCONSISTENT PARTICLE NAME" <* >::const_iterator det; //loop over detectors for(unsigned int id=0; id* detMap = det->second; //build accessor: FopiPidMomWindow win(mom); std::map::const_iterator setit; setit = detMap->find(win); std::map thisli; //in case we found info at the given momentum: if(setit != detMap->end()) { FopiPidProbSet* thisset = setit->second; double rangelow, rangehigh; thisset->getValidityRange(rangelow, rangehigh); std::map::const_iterator partit; //loop over hypotheses: for(partit=partmap->begin(); partit!=partmap->end(); partit++) { if(fVerbose) std::cout<<" particle: "<first.Data()<getProb(partit->first); if(thispart==NULL) { //for TPC, CDC: //if kaon fit not present, assume it has been merged with pion peak and //return that info if(detname.EqualTo("tpc") || detname.EqualTo("cdc") ) { if(partit->first.EqualTo("kaon")) { if(fVerbose) std::cout<<" fetching pion likelihood instead kaon" <<" for mom "<getProb(TString("pion")); } } } if(thispart==NULL) continue; //incoming information for this detector: double pidval = data.getVal(detname); double lh = thispart->getLikelihoodValue(pidval,pidval+0.03); if(pidval < rangelow || pidval > rangehigh) lh = 0.; if(fVerbose) std::cout<<" likelihood = "<first] = lh; }//end loop over hypotheses } else if(fVerbose) std::cout<<" could not get Momentum Window for mom = "<::iterator,bool> ins; ins = fTestMap.insert(std::pair(w,val)); return ins.second; } double FopiPidHub::getDouble(const FopiPidMomWindow& win) const { std::map::const_iterator it; it = fTestMap.find(win); if(it!=fTestMap.end()) return it->second; else return NULL; } void FopiPidHub::buildBookMap() { fBookMap["tpc"] = &fTpcMap; fBookMap["cdc"] = &fCdcMap; fBookMap["bar"] = &fBarMap; fBookMap["rpc"] = &fRpcMap; //fFileMap["tpc"] = ""; //fFileMap["cdc"] = ""; //fFileMap["bar"] = ""; //fFileMap["rpc"] = ""; fCalibValMap["tpc"] = &fTpcCalibMap; fCalibValMap["cdc"] = &fCdcCalibMap; fCalibValMap["bar"] = &fBarCalibMap; fCalibValMap["rpc"] = &fRpcCalibMap; } //if created successfully, caller takes ownership std::map* FopiPidHub::makePartMap(const TString& part) const { std::map* map = new std::map(); (*map)["pion"] = false; (*map)["kaon"] = false; (*map)["proton"] = false; (*map)["deuteron"] = false; if(map->count(part)) { (*map)[part] = true; return map; } else { delete map; return NULL; } } double FopiPidHub::getSumFractions(double mom) const { //not making use of the bools std::map* parts = makePartMap("pion"); double sumfrac = 0.; std::map::const_iterator it; for(it=parts->begin(); it!=parts->end(); it++) { double frac = getFraction(it->first,mom); std::cout<<"Momentum: "<first.Data() <<" fraction: "<0.) sumfrac+=frac; } std::cout<<" TOTAL: "<::const_iterator ioit; if(fVerbose) std::cout<<"FopiPidHub::buildCalibrationMaps() ... "<first.Data() <<"' ..."<second,"read"); if(cfile->IsZombie()) { std::cerr<<" could not open file "<second.Data() <<"; aborting"< >::const_iterator keyit; keyit = fCalibKeyMap.find(ioit->first); std::pair keypair = keyit->second; TString pionkey = keypair.first; TString protkey = keypair.second; //get data for this det TGraphErrors* calPion = (TGraphErrors*) cfile->Get(pionkey); TGraphErrors* calProt = (TGraphErrors*) cfile->Get(protkey); if(calPion == NULL || calProt == NULL ) { std::cerr<<" could not get calibration data" <<" from file; aborting"<first]).first; int runHigh = (fCalibRangeMap[ioit->first]).second; std::cout<<" ... building calibration lookup map for '"<first <<"' and stable range ["<GetN(); unsigned int nPr = calProt->GetN(); double x, y, erry, x2, y2; double mean = 0.; double totErr = 0.; for(unsigned int n=0; nGetPoint(n,x,y); if(x < runLow) continue; if(x > runHigh) break; erry = calPion->GetErrorY(n); mean += (1./erry) * y; totErr += (1./erry); } double meanPi = mean / totErr; mean = 0.; totErr = 0.; for(unsigned int n=0; nGetPoint(n,x,y); if(x < runLow) continue; if(x > runHigh) break; erry = calProt->GetErrorY(n); mean += (1./erry) * y; totErr += (1./erry); } double meanPr = mean / totErr; std::cout<<" found mean values: pion: "< >* >::const_iterator it; it = fCalibValMap.find(ioit->first); if(it == fCalibValMap.end()) { std::cout<<" something went wrong ... "< >* thisCalMap = it->second; double val1, val2; for(unsigned int n=0; nGetPoint(n,x,val1); calProt->GetPoint(n,x2,val2); //check for run number consistency if(std::fabs(x-x2) > 1.e-1) { std::cout<<" INCONSISTENT DATA FOR PI AND PROT.... aborting" < >* >::const_iterator detit; //loop over detectors for(detit=fCalibValMap.begin(); detit!=fCalibValMap.end(); detit++) { if(!uc_data.hasVal(detit->first)) continue; //nothing to correct int run = uc_data.getRunNr(); std::map >* thisMap; thisMap = detit->second; if(!thisMap->count(run)) //empty calib data continue; //check if inside calibration range std::pair calRange; calRange = fCalibRangeMap.find(detit->first)->second; if(run >= calRange.first && run <= calRange.second) continue; //nothing to do std::pair calibData; calibData = thisMap->find(run)->second; double val = uc_data.getVal(detit->first); double CO = uc_data.getCO(detit->first); //if we have our values in a different space than the raw PID data spectra used for computing the //calibration parameters, we need to transform into that raw system first, apply the calibration and //transform back. Usecase: realtive dE/dx spectra double valNorm = val - CO; double m = calibData.first; double t = calibData.second; double newVal = valNorm - m*valNorm - t; ret.setVal(detit->first, newVal+CO,CO); } //end loop over detectors return ret; }