+ fCanvas->cd(3); gPad->Clear(); DrawLegend();
+
+ fCanvas->cd(7);
+
+ if(fHitFile){
+ fHitMipBok->SetTitle(Form("Mips %s",fStHitMip.Data())); fHitMipBok->Modified();
+ fHitCkoBok->SetTitle(Form("Ckov %s",fStHitCko.Data())); fHitCkoBok->Modified();
+ fHitFeeBok->SetTitle(Form("Fdbk %s",fStHitFee.Data())); fHitFeeBok->Modified();
+ }
+ if(fDigFile){fDigBok->SetTitle(fStDig); fDigBok->Modified();}
+ if(fCluFile){fCluBok->SetTitle(fStClu); fCluBok->Modified();}
+ if(fEsdFile){fEsdBok->SetTitle(fStEsd); fEsdBok->Modified();}
+
+}//Draw()
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+void RenderHit(TClonesArray *pHitLst)
+{//used by ReadEvent() to render hits to polymarker structures, one per chamber
+ for(Int_t iHit=0;iHit<pHitLst->GetEntries();iHit++){ //hits loop
+ AliHMPIDHit *pHit = (AliHMPIDHit*)pHitLst->At(iHit); Int_t ch=pHit->Ch(); Float_t x=pHit->LorsX(); Float_t y=pHit->LorsY(); //get current hit
+ switch(pHit->Pid()){
+ case 50000050: fRenCko[ch]->SetNextPoint(x,y);break;
+ case 50000051: fRenFee[ch]->SetNextPoint(x,y);break;
+ default: fRenMip[ch]->SetNextPoint(x,y);break;
+ }//switch hit PID
+// Printf("----------ihit %i ch %i chhit %i MIP %i CKO %i FEE %i",iHit,ch,pHit->Pid());
+ }//hits loop for this entry
+}//RenderHits()
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+void RenderDig(TObjArray *pDigLst)
+{//used by ReadEvent() to render digs to Tbox structures, one per chamber
+
+ for(Int_t iCh=0;iCh<=6;iCh++){ //chambers loop
+ TClonesArray *pDigCham=(TClonesArray*)pDigLst->At(iCh); //get digs list for this chamber
+ nDigs[iCh] = 0;
+ fTotPads[iCh] = pDigCham->GetEntries();
+ Int_t iDigEff=0;
+ for(Int_t iDig=0;iDig<pDigCham->GetEntries();iDig++){ //digs loop
+ AliHMPIDDigit *pDig = (AliHMPIDDigit*)pDigCham->At(iDig); Float_t x=pDig->LorsX(); Float_t y=pDig->LorsY(); //get current hit
+ if((Int_t)pDig->Q()<=qSigmaCut) continue;
+ fRenDig[iCh][iDigEff]->SetX1(x-0.5*AliHMPIDParam::SizePadX());
+ fRenDig[iCh][iDigEff]->SetX2(x+0.5*AliHMPIDParam::SizePadX());
+ fRenDig[iCh][iDigEff]->SetY1(y-0.5*AliHMPIDParam::SizePadY());
+ fRenDig[iCh][iDigEff]->SetY2(y+0.5*AliHMPIDParam::SizePadY());
+ fRenDig[iCh][iDigEff]->SetUniqueID((Int_t)pDig->Q());
+ fBox[iCh][iDigEff]->SetX1(x-0.5*AliHMPIDParam::SizePadX());
+ fBox[iCh][iDigEff]->SetX2(x+0.5*AliHMPIDParam::SizePadX());
+ fBox[iCh][iDigEff]->SetY1(y-0.5*AliHMPIDParam::SizePadY());
+ fBox[iCh][iDigEff]->SetY2(y+0.5*AliHMPIDParam::SizePadY());
+ iDigEff++;
+ nDigs[iCh]++;
+ }//Digit loop
+ }//hits loop for this entry
+}//RenderHits()
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+void RenderClu(TObjArray *pClus)
+{//used by ReadEvent() to render clusters to polymarker structures, one per chamber
+ for(Int_t iCh=0;iCh<=6;iCh++){ //chambers loop
+ TClonesArray *pClusCham=(TClonesArray*)pClus->At(iCh); //get clusters list for this chamber
+ fTotClus[iCh] = pClusCham->GetEntries();
+ for(Int_t iClu=0;iClu<pClusCham->GetEntries();iClu++){ //clusters loop
+ AliHMPIDCluster *pClu = (AliHMPIDCluster*)pClusCham->At(iClu); //get current cluster
+ fRenClu[iCh]->SetNextPoint(pClu->X(),pClu->Y());
+// Printf("RenderClu: ch %i x %f y %f",iCh,pClu->X(),pClu->Y());
+ }//cluster loop
+ }//chamber loop for this entry
+}//RenderClus()
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+void RenderEsd(AliESDEvent *pEsd)
+{//used by ReadEvent() to render ESD to polymarker structures for rings and intersections one per chamber
+ AliHMPIDRecon rec;
+ for(Int_t iTrk=0;iTrk<pEsd->GetNumberOfTracks();iTrk++){//tracks loop to collect cerenkov rings and intersection points
+ AliESDtrack *pTrk=pEsd->GetTrack(iTrk); Int_t ch=pTrk->GetHMPIDcluIdx(); //get track and chamber intersected by it
+ ch/=1000000;
+ Float_t xPc,yPc,xRa,yRa,thRa,phRa;
+ pTrk->GetHMPIDtrk(xPc,yPc,thRa,phRa);;
+
+ xRa = xPc - (fParam->RadThick()+fParam->WinThick()+fParam->GapThick())*TMath::Cos(phRa)*TMath::Tan(thRa); //just linear extrapolation back to RAD
+ yRa = yPc - (fParam->RadThick()+fParam->WinThick()+fParam->GapThick())*TMath::Sin(phRa)*TMath::Tan(thRa);
+
+ if(ch<AliHMPIDParam::AliHMPIDParam::kMinCh||ch>AliHMPIDParam::kMaxCh) continue;//this track does not intersect any chamber
+ Int_t npTrk = fRenTxC[ch]->SetNextPoint(xRa,yRa); //add this intersection point
+ Float_t ckov=pTrk->GetHMPIDsignal(); //get ckov angle stored for this track
+ if(ckov>0){
+ rec.SetTrack(xRa,yRa,thRa,phRa);
+ fRenRin[ch]->SetUniqueID(npTrk);
+ for(Int_t j=0;j<500;j++){
+ TVector2 pos; pos=rec.TracePhot(ckov,j*6.28/500.);
+ if(!AliHMPIDParam::IsInDead(pos.X(),pos.Y())) fRenRin[ch]->SetNextPoint(pos.X(),pos.Y());
+ }
+ }//if ckov is valid
+ }//tracks loop
+}//RenEsd()
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+TString Stack(Int_t evt,Int_t tid)
+{
+// Prints some useful info from stack
+// Arguments: evt - event number. if not -1 print info only for that event
+// tid - track id. if not -1 then print it and all it's mothers if any
+// Returns: mother tid of the given tid if any
+ if(gAL->LoadHeader()) return -1;
+ if(gAL->LoadKinematics()) return -1;
+
+ gAL->GetEvent(evt);
+ AliStack *pStack=gAL->Stack();
+ TParticle *pTrack=pStack->Particle(tid);
+// Int_t mtid=pTrack->GetFirstMother();
+ TString str;
+ str.Append(Form("with P = %7.4f (%7.4f,%7.4f,%7.4f) GeV/c ",pTrack->P(),pTrack->Px(),pTrack->Py(),pTrack->Pz()));
+ gAL->UnloadHeader(); gAL->UnloadKinematics();
+ return str;
+}
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+void DispTB(TString t0,TString t1,TString t2,TString t3)
+{
+ fCanvasImp->SetStatusText(t0,0);
+ fCanvasImp->SetStatusText(t1,1);
+ fCanvasImp->SetStatusText(t2,2);
+ fCanvasImp->SetStatusText(t3,3);
+}
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Bool_t FindPos(TVector3 xyz,Int_t &cham,Int_t §,Int_t &gap,Int_t &padX,Int_t &padY)
+{
+// It finds the chamber parameters for a given point
+// Arguments: xyz coordinates of a given point in MARS
+// Returns: cham chamber ID ( 0-6 )
+// sect sector ID ( 0-5 )
+// padX X (integer) of the pad in X in the given sector (1-80)
+// padY Y (integer) of the pad in Y in the given sector (1-48)
+ cham = -1;
+ TGeoNode *node = gGeoManager->FindNode(xyz.X(),xyz.Y(),xyz.Z());
+ if(!node) return kFALSE;
+ TGeoVolume *vol = node->GetVolume();
+ if(!vol) return kFALSE;
+ TGeoManager *geo = vol->GetGeoManager();
+ if(!geo) return kFALSE;
+ Int_t i=0;
+ while(geo->GetMother(i)) {
+ TString s = geo->GetMother(i)->GetName();
+// if(s.Contains("Hcel_")) padX=(Int_t)(s.Remove(0,5)).Atof();
+// if(s.Contains("Hrow_")) padY=(Int_t)(s.Remove(0,5)).Atof();
+// if(s.Contains("Hsec_")) sect=(Int_t)(s.Remove(0,5)).Atof();
+// if(s.Contains("Hmp_")) cham=(Int_t)(s.Remove(0,4)).Atof();
+ if(s.Contains("Hcel_")) padX=geo->GetMother(i)->GetNumber();
+ if(s.Contains("Hrow_")) padY=geo->GetMother(i)->GetNumber();
+ if(s.Contains("Hsec_")) sect=geo->GetMother(i)->GetNumber();
+ if(s.Contains("Hmp_")) cham=geo->GetMother(i)->GetNumber();
+ i++;
+ }
+ return (cham==-1) ? kFALSE : kTRUE;
+}
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+void DisplayInfo(Int_t evt,Int_t px, Int_t py)
+{
+ if(!gPad) return;
+ TVirtualPad *pPad=gPad->GetSelectedPad();
+ Int_t padN = pPad->GetNumber()-1;
+ if(padN<0 || padN>8) return;
+ Int_t ch,pc,padX,padY;
+ ch = fChamN[padN];
+ if(ch<0) return;
+ TString text0,text1,text2,text3;
+
+ Float_t x=pPad->AbsPixeltoX(px); Float_t y=pPad->AbsPixeltoY(py);
+ fParam->Lors2Pad(x,y,pc,padX,padY);
+ TVector3 xyz=fParam->Lors2Mars(ch,x,y);
+
+ if(padX>=0&&padY>=0) {
+ text0.Append(Form("Pad(%i,%i)-LORS(%6.2f,%6.2f)-MARS(%7.2f,%7.2f,%7.2f) A(%6.2f,%6.2f)",padX,padY,x,y,xyz.X(),xyz.Y(),xyz.Z(),
+ xyz.Theta()*TMath::RadToDeg(),xyz.Phi()*TMath::RadToDeg()));
+ text1.Append(Form("Module %i Sector %i",ch,pc));
+ text2="";
+ text3.Append(Form("Pads = %i - Clusters = %i - Occupancy %5.2f%%",fTotPads[ch],fTotClus[ch],100.*fTotPads[ch]/(144.*160.)));
+ }
+
+ TObject *obj = fCanvas->GetSelected();
+ TString name = obj->GetName();
+
+// Find object DIGIT
+
+ if(name=="") {DispTB(text0,text1,text2,text3);return;} // TLatex not interesting
+
+ if(name.Contains("TBox")) {
+ TBox *box = (TBox*)obj;
+ if(box->GetUniqueID()==0) return; // just black frame hit!
+ text2.Append(Form("charge = %i ADC",box->GetUniqueID()));
+ DispTB(text0,text1,text2,text3);
+ return;
+ }
+//
+// Find object HITs CLUSTER TRACK and RING (based on TPolyMarker and symbol)
+//
+ TPolyMarker *b = (TPolyMarker*)obj;
+
+ const Int_t big = 9999;
+
+ // check if point is near one of the points
+ Int_t distance = big;
+ Int_t index=0;
+
+ Double_t *xPol = b->GetX();
+ Double_t *yPol = b->GetY();
+
+ for(Int_t i=0;i<b->Size();i++) {
+ Int_t pxp = pPad->XtoAbsPixel(pPad->XtoPad(xPol[i]));
+ Int_t pyp = pPad->YtoAbsPixel(pPad->YtoPad(yPol[i]));
+ Int_t d = TMath::Abs(pxp-px) + TMath::Abs(pyp-py);
+ if (d < distance) {distance = d; index=i;}
+ }
+
+ Int_t symbol = b->GetMarkerStyle();
+
+ // kOpenTriangleUp Hit Mip
+ // kOpenCircle Hit Ckov
+ // kOpenDiamond Hit Feedback
+ // kStar Cluster
+ // kPlus Track
+ // kFullDotSmall Ring
+
+ // Case Hit Mip of Hit Ckov or Hit Feedback
+ if(symbol==kHitMip || symbol==kHitCko || symbol==kHitFee) {
+ if(evt!=kButton1Down) return;
+ TString nameHit;
+ Int_t iCko[7]={0,0,0,0,0,0,0};
+ Int_t iFee[7]={0,0,0,0,0,0,0};
+ Int_t iMip[7]={0,0,0,0,0,0,0};
+ Int_t iHit;
+ Int_t chHit;
+ Int_t indHit=0;
+
+ Int_t indTrk = b->GetUniqueID(); // track index
+ for(Int_t iEnt=0;iEnt<fHitTree->GetEntries();iEnt++){//entries loop
+ fHitTree->GetEntry(iEnt);
+ for(iHit=0;iHit<fHitLst->GetEntries();iHit++) { //hits loop
+ AliHMPIDHit *pHit = (AliHMPIDHit*)fHitLst->At(iHit);
+ chHit = pHit->Ch();
+ Int_t pid = pHit->Pid();
+ if(pid==50000050) iCko[chHit]++;
+ else if(pid==50000051) iFee[chHit]++;
+ else iMip[chHit]++;
+
+ if(symbol==kHitMip && ch==chHit && index==iMip[chHit]-1) {indTrk=iEnt;indHit = iHit;break;}
+ if(symbol==kHitCko && ch==chHit && index==iCko[chHit]-1) {indTrk=iEnt;indHit = iHit;break;}
+ if(symbol==kHitFee && ch==chHit && index==iFee[chHit]-1) {indTrk=iEnt;indHit = iHit;break;}
+ }
+ }
+ fHitTree->GetEntry(indTrk);
+ AliHMPIDHit *pHit = (AliHMPIDHit*)fHitLst->At(indHit);
+
+ Int_t tid = pHit->Tid();
+
+ TString str = Stack(fEvt,tid);
+
+ Float_t x=pHit->LorsX();
+ Float_t y=pHit->LorsY();
+ Float_t charge = pHit->Q();
+
+ TVector3 v = fParam->Lors2Mars(pHit->Ch(),pHit->LorsX(),pHit->LorsY());
+ Int_t cham,sect,gap,padX,padY;
+ FindPos(v,cham,sect,gap,padX,padY);
+
+ if(pHit->Pid()==50000050) {nameHit = " Cherenkov Photon ";}
+ else if(pHit->Pid()==50000051) {nameHit = " Feedback Photon ";}
+ else if(fPdg->GetParticle(pHit->Pid())) nameHit = fPdg->GetParticle(pHit->Pid())->GetName();
+ nameHit.Append(Form(" (tid %i)",tid));
+ text0="";text0.Append(Form("Hit(%5.2f,%6.2f) LORS - Pad Volume(%i,%i) - hit %i/%i",x,y,padX,padY,indHit+1,fHitLst->GetEntries()));
+ text2="";text2.Append(Form("Q = %7.2f ADC",charge));
+ text3="";text3="Particle: "+ nameHit +" "+ str;
+ } // Hit
+ else if (symbol==kCluster) {
+ TClonesArray *pClusCham=(TClonesArray*)fCluLst->At(ch); //get clusters list for this chamber
+ AliHMPIDCluster *pClu = (AliHMPIDCluster*)pClusCham->At(index); //get current cluster
+ text0="";text0.Append(Form("CLUSTER: x %6.2f y %6.2f",pClu->X(),pClu->Y()));
+ text2="";text2.Append(Form("charge = %i ADC",(Int_t)pClu->Q()));
+ }
+ else if (symbol==kTrack || symbol==kRing) {
+ if(symbol==kRing) index = b->GetUniqueID();
+ AliESDtrack *pTrk=fEsd->GetTrack(index);
+ Float_t xPc,yPc,thRa,phRa,xRa,yRa;
+ Int_t ch = AliHMPIDTracker::IntTrkCha(pTrk,xPc,yPc,xRa,yRa,thRa,phRa);
+ text0="";text0.Append(Form("TRACK n.%d: x %6.2f y %6.2f at PC plane in chamber %i",index,xPc,yPc,ch));
+ text2="";text2.Append(Form("p = %7.2f GeV/c",pTrk->GetP()));
+ Float_t ckov=pTrk->GetHMPIDsignal();
+ Double_t prob[5];
+ pTrk->GetHMPIDpid(prob);
+ if(ckov>0){
+ Float_t x,y;Int_t q,nacc; pTrk->GetHMPIDmip(x,y,q,nacc);
+ text3="";text3.Append(Form("Theta Cherenkov %5.3f with %i photons | e %5.1f%% | u %5.1f%% | pi %5.1f%% | K %5.1f%% | p %5.1f%%",
+ pTrk->GetHMPIDsignal(),nacc,prob[0]*100,prob[1]*100,prob[2]*100,prob[3]*100,prob[4]*100));
+ }
+ }
+//Update toolbar status
+
+ DispTB(text0,text1,text2,text3);
+}
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+void CloseInfo()
+{
+}