// $Id: hpairfl.cc,v 1.13 2009-07-15 11:41:59 halo Exp $ // Author: Thomas.Eberl@ph.tum.de, last modified : 2006-03-28 18:31:49 // // --------------------------------------------------------------------------- //_HADES_CLASS_DESCRIPTION /////////////////////////////////////////////////////////////////////////////// // // HPairFL // // Static function library of module "pairs" // /////////////////////////////////////////////////////////////////////////////// // using namespace std; // --------------------------------------------------------------------------- #include // --------------------------------------------------------------------------- #include "TFile.h" #include "TH1F.h" #include "TLorentzVector.h" #include "TObjArray.h" #include "TString.h" #include "TVector3.h" // --------------------------------------------------------------------------- #include #include #include #include #include #include #include #include // --------------------------------------------------------------------------- #include "hpidparticle.h" #include "pairsdef.h" // --------------------------------------------------------------------------- #include "hpairfl.h" // --------------------------------------------------------------------------- ClassImp(HPairFL) // --------------------------------------------------------------------------- HPairFL::HPairFL(void) { } // --------------------------------------------------------------------------- HPairFL::~HPairFL(void) { } // --------------------------------------------------------------------------- HCategory* HPairFL::buildLinearCategory(Cat_t cat,const Text_t* catName) { HCategory *pCat = 0; if (gHades && gHades->getCurrentEvent()) { if ((pCat = ((HEvent*)(gHades->getCurrentEvent()))->getCategory(cat))) return pCat; else { pCat = new HLinearCategory(catName); if (!pCat) ::Error("HPairFL::buildLinearCategory", "Cannot create new category"); } } else { ::Error("HPairFL::buildLinearCategory","Cannot access current event"); return pCat; } return pCat; } // --------------------------------------------------------------------------- HCategory* HPairFL::getCategory(Cat_t cat, Bool_t bWarning) { // Find HCategory if gHades->getCurrentEvent() is accessible HEvent *pEvent; HCategory *pCat; if((gHades == NULL) || ((pEvent = gHades->getCurrentEvent()) == NULL)) { if(bWarning) { ::Error("HPairFL::getCategory", "Cannot access current event"); } return NULL; } if((pCat = pEvent->getCategory(cat)) == NULL) { if(bWarning) ::Error("HPairFL::getCategory", "No category: %d", cat); } return pCat; } // --------------------------------------------------------------------------- void HPairFL::saveHistos(TFile* pFileOut, TObjArray* pHistArray) { // use this function to save histos every n events // assumes that you have opened a file and that your // histograms are stored in a TObjArray if(!pFileOut->IsOpen()) { TString filename(pFileOut->GetName()); pFileOut=TFile::Open(filename.Data(),"UPDATE"); cout<<"Warning: File "<GetName()<<" was reopened."<Print(); } pFileOut->cd(); // write histograms for (Int_t i=0;i<(pHistArray->GetLast()+1);i++) { ( (TH1*)(*pHistArray)[i] )->Write(); } } // --------------------------------------------------------------------------- void HPairFL::printBitField(const Int_t in) { Int_t nBits = sizeof(in) * 8 + 1; Char_t* c = new Char_t[nBits]; for (Int_t k=0; k<=nBits-1 ; k++) c[k]=48; //0 for (Int_t k=0; k<=nBits-1 ; k++) if ( in & (1 << k) ) c[nBits-1-k]=49;//1 c[nBits-1]=13; // CR cout<<"Bit field: "< nBits-1) { ::Error("HPairFL::setBit","bit position out of range !"); } Int_t SETTHIS = (1 << pos); in |= SETTHIS; } // --------------------------------------------------------------------------- Int_t HPairFL::getBit(UChar_t pos, const Int_t in) { // start counting from 0 for the position ! // i.e.: 0,1,2,3,4,5,6, .... UInt_t nBits = sizeof(in) * 8; if (pos > nBits-1) { ::Error("HPairFL::setBit","bit position out of range !"); return -1; } if ( in & (1 << pos) ) return 1; else return 0; } // --------------------------------------------------------------------------- void HPairFL::clearBit(UChar_t pos, Int_t& in) { // start counting from 0 for the position ! // i.e.: 0,1,2,3,4,5,6, .... UInt_t nBits = sizeof(in) * 8; if (pos > nBits-1) { ::Error("HPairFL::setBit","bit position out of range !"); } Int_t SETTHIS = (Int_t(1) << pos); in &= ~SETTHIS; } // --------------------------------------------------------------------------- void HPairFL::setBit(UInt_t pos, Int_t& in) { // start counting from 0 for the position ! // i.e.: 0,1,2,3,4,5,6, .... UInt_t nBits = sizeof(in) * 8; if (pos > nBits-1) { ::Error("HPairFL::setBit","bit position out of range !"); } Int_t SETTHIS = (1 << pos); in |= SETTHIS; } // --------------------------------------------------------------------------- Int_t HPairFL::getBit(UInt_t pos, const Int_t in) { // start counting from 0 for the position ! // i.e.: 0,1,2,3,4,5,6, .... UInt_t nBits = sizeof(in) * 8; if (pos > nBits-1) { ::Error("HPairFL::setBit","bit position out of range !"); return -1; } if ( in & (1 << pos) ) return 1; else return 0; } // --------------------------------------------------------------------------- void HPairFL::clearBit(UInt_t pos, Int_t& in) { // start counting from 0 for the position ! // i.e.: 0,1,2,3,4,5,6, .... UInt_t nBits = sizeof(in) * 8; if (pos > nBits-1) { ::Error("HPairFL::setBit","bit position out of range !"); } Int_t SETTHIS = (1 << pos); in &= ~SETTHIS; } // --------------------------------------------------------------------------- Int_t HPairFL::countPositiveBits(const Int_t in) { Int_t nBits = sizeof(in) * 8; Int_t cnt=0; for (Int_t k=0; k<=nBits-1 ; k++) if ( in & (1 << k) ) cnt++; return cnt; } // --------------------------------------------------------------------------- /* // --------------------------------------------------------------------------- TH1F* HPairFL::createVarBinHisto(TH1* h,Float_t* xbins,Int_t nbins,Bool_t kNorm=kTRUE,Bool_t kErr=kTRUE) { // ASSUMPTION: input histo is __NOT__ normalized to bin width ! TString name(h->GetName()); name.Append("_rebsig"); //create new histogram with new binning TH1F * hn = new TH1F(name.Data(),"inv_mass signal",nbins,xbins); //hn->Dump(); hn->Sumw2(); h->Sumw2(); cout<<"Array input size: "<GetNbinsX()<GetNbinsX()<GetNbinsX()+1]; for (Int_t k=0;kGetNbinsX()+1;k++) errn[k]=0.; cout<<"Error array created with size: "<GetNbinsX()+1<GetNbinsX()+1;j++) { Int_t i = h->GetBin(j); //find center of bin of old histo Float_t cc = h->GetBinCenter(i); //stop if old bins are beyond new bins if (cc > hn->GetBinCenter(hn->GetBin(hn->GetNbinsX()))+ hn->GetBinWidth(hn->GetBin(hn->GetNbinsX()))/2. ) break; //fill old content in new bin number bin Int_t bin = hn->Fill(cc,h->GetBinContent(i)); //check bounds, sum errors quadratic, save in new bin if (kErr && bin>=0 && bin<=hn->GetNbinsX()) errn[bin]+=h->GetBinError(i)*h->GetBinError(i); } // Normalization to bin width if (kNorm) { for (Int_t j=1;jGetNbinsX()+1;j++) { Int_t bin = hn->GetBin(j); hn->SetBinContent( bin, hn->GetBinContent(bin)/ hn->GetBinWidth(bin) ); } } // Set errors, rescale if normalized if (kErr) { for (Int_t j=0;jGetNbinsX()+1;j++) { Int_t bin = hn->GetBin(j); hn->SetBinError(bin,TMath::Sqrt(errn[j])); if (kNorm) hn->SetBinError(bin,hn->GetBinError(bin)/hn->GetBinWidth(bin)); } } delete [] errn; return hn; } // --------------------------------------------------------------------------- TH1F* HPairFL::getSameEventCombinatorialBackground(TH1F *pp, TH1F* nn, Int_t typ) { Char_t name[256]; sprintf(name,"%s_back",pp->GetName()); TH1F *bground = new TH1F(name,"comb.backg.",pp->GetNbinsX(),0,pp->GetXaxis()->GetXmax()); bground->Sumw2(); Double_t massPP, massNN; Double_t errPP, errNN; Int_t maxBins = pp->GetNbinsX(); for(Int_t i = 1; i < maxBins+1; i++) {// skip underflow bin massPP = pp->GetBinContent(i); massNN = nn->GetBinContent(i); errPP = pp->GetBinError(i); errNN = nn->GetBinError(i); if(typ == 0 ) { bground->SetBinContent(i,2.*TMath::Sqrt(massPP*massNN)); if(massNN>0. && massPP>0. && errPP*errPP*massNN*massPP>=0.) bground->SetBinError(i,TMath::Sqrt( errPP*errPP*massNN/massPP + errNN*errNN*massPP/massNN )); } if(typ == 1) { bground->SetBinContent(i,massPP+massNN); Float_t radix = errPP*errPP + errNN*errNN; if (radix>=0.) bground->SetBinError(i,TMath::Sqrt(radix)); } } return bground; } // --------------------------------------------------------------------------- TH1F* HPairFL::subtractHistogram(TH1F *pn, TH1F* backg) { Char_t name[256]; sprintf(name,"%s_sig",pn->GetName()); TH1F *invMass = new TH1F(name,"inv_mass_signal",pn->GetNbinsX(),0,pn->GetXaxis()->GetXmax()); invMass->Sumw2(); invMass->Add(pn,backg,1.,-1.); return invMass; } // --------------------------------------------------------------------------- void HPairFL::printHisto(TH1F* h) { Int_t nbXbins = h->GetNbinsX(); cout<<"Number of bins in histo: "<GetBin(j); // return bin, redundant here Float_t cc = h->GetBinCenter(i); Float_t errn= h->GetBinError(i); Float_t width=h->GetBinWidth(i); Float_t con=h->GetBinContent(i); if (cc > 1000.) break; Float_t relerr=-1.; if (con>0.) relerr = errn/con*100.; cout<<"Index: "<Vect(); TVector3 pvec2 = p2->Vect(); Float_t opang=pvec1.Angle(pvec2);//in radians Float_t invMass=2.*TMath::Sin(opang/2.)*TMath::Sqrt(p1->P()*p2->P()); if (invMass>0.) return invMass; else return -1.; } // --------------------------------------------------------------------------- Float_t HPairFL::calcInvMass(TLorentzVector* t1, TLorentzVector* t2) { // use this function only for beta = 1 particles TVector3 pvec1 = t1->Vect(); TVector3 pvec2 = t2->Vect(); Float_t opang=pvec1.Angle(pvec2);//in radians Float_t invMass=2.*TMath::Sin(opang/2.)*TMath::Sqrt(t1->P()*t2->P()); if (invMass>0.) return invMass; else return -1.; } // --------------------------------------------------------------------------- HGeantKine* HPairFL::findParent(HGeantKine *kine,HIterator* iter_kine2) { Int_t aPar, aMed, aMech; kine->getCreator(aPar,aMed,aMech); if (aPar){ HGeantKine *kine2=0; Int_t aTrackParent,aIDParent; //iter_kine2 = (HIterator*)(cat->MakeIterator("native")); iter_kine2->Reset(); while((kine2=(HGeantKine *)iter_kine2->Next())!=0) { kine2->getParticle(aTrackParent,aIDParent); if (aPar == aTrackParent) { return kine2; } } } return 0; } // --------------------------------------------------------------------------- HGeantKine* HPairFL::findParent(HGeantKine *kine,HCategory* cat) { Int_t aPar, aMed, aMech; kine->getCreator(aPar,aMed,aMech); if (aPar){ HIterator* iter_kine2 = NULL; HGeantKine *kine2=0; Int_t aTrackParent,aIDParent; iter_kine2 = (HIterator*)(cat->MakeIterator("native")); iter_kine2->Reset(); while((kine2=(HGeantKine *)iter_kine2->Next())!=0) { kine2->getParticle(aTrackParent,aIDParent); if (aPar == aTrackParent) { return kine2; } } // safe delete iter_kine2 if(iter_kine2) { delete iter_kine2; iter_kine2 = NULL; } } return 0; } // --------------------------------------------------------------------------- Float_t HPairFL::calcVertex(HPidParticle *p1, HPidParticle *p2, TVector3 *vertex, TVector3 *distance) { // calcVertex should return // 1. the vertex of two tracks (no weights included, so it returns the // center of closest approach vector) // 2. a vector with direction and magnitude of the distance // (using stefanos algebra to calculate the magnitude, root cross product // to give the direction) HGeomVector hoff[2]; HGeomVector hdir[2]; HGeomVector hvertex; HGeomVertexFit hfitter; TVector3 dir[2]; Float_t dist; Float_t det1, det2; // extract coordinates from p1, p2, fill them into HGeomVector // to use Manuels fitter hoff[0].setXYZ(p1->getR()*TMath::Cos(p1->phiDeg()*TMath::DegToRad() + TMath::PiOver2()), p1->getR()*TMath::Sin(p1->phiDeg()*TMath::DegToRad() + TMath::PiOver2()), p1->getZ()); hoff[1].setXYZ(p2->getR()*TMath::Cos(p2->phiDeg()*TMath::DegToRad() + TMath::PiOver2()), p2->getR()*TMath::Sin(p2->phiDeg()*TMath::DegToRad() + TMath::PiOver2()), p2->getZ()); dir[0] = p1->Vect(); dir[1] = p2->Vect(); hdir[0].setXYZ(dir[0].X(),dir[0].Y(),dir[0].Z()); hdir[1].setXYZ(dir[1].X(),dir[1].Y(),dir[1].Z()); hfitter.reset(); for (Int_t i = 0; i < 2; i++) { hfitter.addLine(hoff[i],hdir[i]); } hfitter.getVertex(hvertex); vertex->SetXYZ(hvertex.getX(),hvertex.getY(),hvertex.getZ()); // Function to calculate the distance between two lines in the space // c.f. Stefano det1 = ( (hoff[0].getX()-hoff[1].getX()) * (hdir[0].getY()*hdir[1].getZ()-hdir[0].getZ()*hdir[1].getY()) - (hoff[0].getY()-hoff[1].getY()) * (hdir[0].getX()*hdir[1].getZ()-hdir[0].getZ()*hdir[1].getX()) + (hoff[0].getZ()-hoff[1].getZ()) * (hdir[0].getX()*hdir[1].getY()-hdir[0].getY()*hdir[1].getX()) ); det2 = TMath::Sqrt( (hdir[0].getX()*hdir[1].getY() - hdir[0].getY()*hdir[1].getX()) * (hdir[0].getX()*hdir[1].getY() - hdir[0].getY()*hdir[1].getX()) + (hdir[0].getX()*hdir[1].getZ() - hdir[0].getZ()*hdir[1].getX()) * (hdir[0].getX()*hdir[1].getZ() - hdir[0].getZ()*hdir[1].getX()) + (hdir[0].getY()*hdir[1].getZ() - hdir[0].getZ()*hdir[1].getY()) * (hdir[0].getY()*hdir[1].getZ() - hdir[0].getZ()*hdir[1].getY()) ); // Create a distance vector and scale it with dist *distance = dir[0].Cross(dir[1]); if (det2==0) { dist = -1.; } else { dist = TMath::Abs(det1/det2); distance->SetMag(dist); } return dist; } // --------------------------------------------------------------------------- void HPairFL::dumpKine(HGeantKine *kine) { if (kine) { Int_t aTrack, aID; Int_t aPar, aMed, aMech; Float_t ax, ay, az; Float_t apx, apy, apz; Float_t aInfo, aWeight; Float_t ptot; kine->getParticle(aTrack,aID); kine->getCreator(aPar,aMed,aMech); kine->getVertex(ax,ay,az); kine->getMomentum(apx,apy,apz); kine->getGenerator(aInfo,aWeight); ptot=kine->getTotalMomentum(); cout<<"----------------------GEANT KINE------------------------"<(n) {N2-->N1} //according to the function ax+by //and decides whether this value is already stored or not //the array tuple is assumed to be init to -2 // N.B.!! here (i,j) is the same tuple as (j,i) !!! //dynamically choose multiplicator Int_t base=10; Int_t cnt=1; while ((max%cnt) "<-1) { tuple[index]=f1;//store new 2-tuple //cout<<"newly stored: "<