#ifndef PAMVMCTRKSD_H #define PAMVMCTRKSD_H #ifdef __cplusplus extern "C" { #endif #define GPINIT gpinit_ #define GPUDIFFUSION gpudiffusion_ #define GPBEGIN gpbegin_ #define GPDSPE gpdspe_ #define GPDCSPE gpdcspe_ extern void GPINIT(float*, float*); extern void GPBEGIN(); extern void GPUDIFFUSION(int* ,float* ,int*, float* ,float* ,int*); extern void GPDSPE(); extern void GPDCSPE(float*, float*, float*, float*, float*, float* ); #ifdef __cplusplus } #endif #include #include "PamVMCDetectorSD.h" #include "PamVMCTrkHit.h" #include "PamVMCTrkF77GpsSpe.h" #include "PamVMCTrkF77GpcSpe.h" #include "PamVMCTrkDig.h" #include #include #include #include #include class pGPSSPEData; class PamVMCTrkSD: public PamVMCDetectorSD{ private: cGPCSPE * fGPCSPE; cGPSSPE * fGPSSPE; pGPSSPEHits * fgps; public: PamVMCTrkSD():PamVMCDetectorSD("PamVMCTrkHit","TSPA",1000) { fGPCSPE = 0; fGPSSPE = 0; fgps = new pGPSSPEHits(); Init(); }; virtual ~PamVMCTrkSD(){ delete fgps;} //Loading SPE hit resolution data from resxy_new.root //which should present in the same directory then application library void Init(){ TString G4WORKDIR=gSystem->Getenv("G4WORKDIR"); TString PLATFORM=gSystem->Getenv("PLATFORM"); TFile * resspe = new TFile(G4WORKDIR+"/lib/tgt_"+PLATFORM+"/resxy_new.root"); if(resspe->IsOpen()){ TH1F * hsx; TH1F * hsy; TString num; float cwx[11][1000]; float cwy[11][1000]; for(Int_t j=0; j<11; j++){ num=(::Form("%4i",1000+2*j)); resspe->GetObject("h"+num+";1",hsx); num=(::Form("%4i",2000+2*j)); resspe->GetObject("h"+num+";1",hsy); if ((hsx)&&(hsy)){ for(Int_t i = 0; i<1000; i++){ cwx[j][i]=hsx->GetBinContent(i); cwy[j][i]=hsy->GetBinContent(i); } }else{ cout<<"!!!WARNING: SPE hit resolution data file corrupted!!!"< Register(fdname.Data(),"TClonesArray", &fHitColl); TString a=fHitColl?"exist":"not exist"; PamRootManager::Instance()-> Register("GPSSPE","pGPSSPEHits",&fgps); if (fdig) ((PamVMCTrkDig*)fdig)->RegisterTrkData(fgps); } virtual void ClearHitColl(){ fnohit=0; (*fHitColl).Clear("C"); fgps->Clear(); } virtual void Compress(){fgps->Compress(); (*fHitColl).Compress();} virtual void SaveTrkHit(const char * dname){ PamVMCDetectorHit * t=(PamVMCDetectorHit*) CreateTrkHit(dname); *t=*fhit; } virtual PamVMCTrkHit * CreateTrkHit(const char * dname) { fdetID=(PamVMCGeoID*)fdmap(dname); return CreateTrkHit(); } virtual PamVMCTrkHit * CreateTrkHit() { PamVMCTrkHit *hit= (PamVMCTrkHit *) fHitColl->New(fnohit++); InitHit(); SetTrkHit(hit); return hit; } void FillHit(fin f,TVirtualMC *g){ ffi=f; //g->SetMaxStep(0.001); // 10 um switch(f) { case ENTERING: CleanHit(); FillVolID(); InitHit(); //cout<<">>>ENTERING in PLANE: "<GetParticle(gMC->TrackPid()); //Double_t mass = particlePDG->Mass(); //Double_t x,y,z,e; //g->TrackMomentum(x,y,z,e); //Double_t P0 = TMath::Sqrt(x*x+y*y+z*z); //Double_t energy = TMath::Sqrt(P0*P0+mass*mass)-mass; //cout<<"stepping... Stepsize"<TrackStep()*10000<<"um "<<" particle PDG is:"<TrackPid()<<" Kin.energy:"<Edep()) PreDigit(); break; } switch(f){ case EXITING: //cout<<"<<TrackPid()<GetEREL()){ SaveTrkHit(fdname.Data()); } break; default: break; } } /*This method for simulation spatial tracker resolution, use data from resxy_new.root file. Calls on track exiting when we know XOUT,YOUT,ZOUT */ void SetTrkHit(PamVMCTrkHit *t){ float xin = (float)fhit->GetXIN(); float yin = (float)fhit->GetYIN(); float zin = (float)fhit->GetZIN(); float xout = (float)fhit->GetXOUT(); float yout = (float)fhit->GetYOUT(); float zout = (float)fhit->GetZOUT(); gpdcspe_(&xin, &yin, &zin, &xout, &yout, &zout); fGPCSPE=&gpcspe_; // cout<<"GPCSPE"<xave<<" "<yave<<" "<< // fGPCSPE->zave<<" " <nxmult<<" "<nymult<SetHit(t); } /*This method designed for calculaton energy release on trakcer strips is calls for each step*/ virtual void PreDigit(){ Double_t x,y,z,px,py,pz,e,p; gMC->TrackMomentum(px,py,pz,e); p=sqrt(px*px+py*py+pz*pz); if(p){ //sometimes FLUKA vives u p=0 gGeoManager->cd(gMC->CurrentVolPath()); int iact=ffi; float *trpar = new float[6]; gMC->TrackPosition(x,y,z); trpar[0]=(float)x; trpar[1]=(float)y; trpar[2]=(float)z; trpar[3]=(float)px/p; trpar[4]=(float)py/p; trpar[5]=(float)pz/p; int *numvol = new int[2]; numvol[0]=GetPlaneID(); //if (numvol[0]==6) numvol[0]=0; numvol[1]=GetPadID(); float deloss=(float)gMC->Edep(); float step=(float)gMC->TrackStep(); int itypar=TDatabasePDG::Instance()->ConvertPdgToGeant3(gMC->TrackPid()); gpudiffusion_(&iact, trpar, numvol, &deloss, &step, &itypar); delete numvol; delete trpar; } } /*This method calculate ADC amplitudes from strips. It use data arrays PROXTANTI, PROYTANTI, GLOBSTRIPX, GLOBSTRIPY in common. Calls after each event from application */ virtual void Digitize(){ gpdspe_(); fGPSSPE = &gpsspe_; fgps->SetData(fGPSSPE); } Int_t GetPlaneID(){ Int_t pl=Int_t((fhit->GetPOS()-1)/6.)+1; return pl; } Int_t GetPadID(){ return (fhit->GetPOS()-(GetPlaneID()-1)*6); } ClassDef(PamVMCTrkSD,1) }; #endif // PAMVMCTRKSD_H