#include "R3BCHIMERATreat.h" #include "TClonesArray.h" #include "FairRootManager.h" #include "FairRunAna.h" #include "FairRuntimeDb.h" // includes for modeling #include "TGeoManager.h" #include "TParticle.h" #include "TVirtualMC.h" #include "TGeoMatrix.h" #include "TGeoMaterial.h" #include "TGeoMedium.h" #include "TGeoBBox.h" #include "TGeoCompositeShape.h" #include "TGeoShapeAssembly.h" #include "TVector3.h" #include "TMath.h" #include "TRandom.h" #include "TH1F.h" #include "TH2F.h" #include #include #include "R3BChimeraPoint.h" #include "R3BMCTrack.h" using std::cout; using std::endl; R3BCHIMERATreat::R3BCHIMERATreat() : FairTask("R3B Land Digitization scheme ") { fVerbose = 1; } R3BCHIMERATreat::R3BCHIMERATreat(Int_t verbose) : FairTask("R3B Land Digitization scheme ", verbose) { fVerbose = verbose; } R3BCHIMERATreat::~R3BCHIMERATreat() { } void R3BCHIMERATreat::SetParContainers() { // Get run and runtime database FairRunAna* run = FairRunAna::Instance(); if ( ! run ) Fatal("SetParContainers", "No analysis run"); FairRuntimeDb* rtdb = run->GetRuntimeDb(); if ( ! rtdb ) Fatal("SetParContainers", "No runtime database"); /*pc fLandDigiPar = (R3BLandDigiPar*)(rtdb->getContainer("R3BLandDigiPar")); if ( fVerbose && fLandDigiPar ) { cout << "-I- R3BCHIMERATreat::SetParContainers() "<< endl; cout << "-I- Container R3BLandDigiPar loaded " << endl; } pc*/ } InitStatus R3BCHIMERATreat::Init() { // Get input array FairRootManager* ioman = FairRootManager::Instance(); if ( ! ioman ) Fatal("Init", "No FairRootManager"); fChimeraPoints = (TClonesArray*) ioman->GetObject("ChimeraPoint"); fChimeraMCTrack = (TClonesArray*) ioman->GetObject("MCTrack"); cout << "linea 82 di R3BCHIMERATreat::Init()" << endl; if ( ! gGeoManager )cout << "Init " << " No GeoManager"<Register("FASTSLOW", "Sim Fast Slow", fs, kTRUE); /*pc // Register output array LandDigi fLandDigi = new TClonesArray("R3BLandDigi",1000); ioman->Register("LandDigi", "Digital response in Land", fLandDigi, kTRUE); // Parameter retrieval // Only after Init one retrieve the Digitization Parameters! npaddles = fLandDigiPar->GetMaxPaddle()+1; nplanes = fLandDigiPar->GetMaxPlane(); paddle_per_plane=(npaddles-1)/nplanes; cout<<"# paddles: "<GetXaxis()->SetTitle("Time (ns)"); hPMl->GetYaxis()->SetTitle("Counts"); hPMr = new TH1F("PM_right","Arrival times of right PM",1000,0.,1000.); hPMr->GetXaxis()->SetTitle("Time (ns)"); hPMr->GetYaxis()->SetTitle("Counts"); hTotalLight = new TH1F("Total_Light","Total light detected (energy equivalent)",5000,0.,1000.); hTotalLight->GetXaxis()->SetTitle("Energy (MeV)"); hTotalLight->GetYaxis()->SetTitle("Counts"); hTotalLight1 = new TH1F("Total_Light1","Total light detected (energy equivalent)",55,-0.02,1.08); hTotalLight1->GetXaxis()->SetTitle("Energy/Ebeam"); hTotalLight1->GetYaxis()->SetTitle("Counts"); hTotalEnergy = new TH1F("Total_Energy","Total energy detected",5000,0.,5000.); hTotalEnergy->GetXaxis()->SetTitle("Energy (MeV)"); hTotalEnergy->GetYaxis()->SetTitle("Counts"); hTotalEnergy1 = new TH1F("Total_Energy1","Total energy detected / Ebeam",55,-0.02,1.08); hTotalEnergy1->GetXaxis()->SetTitle("Energy/Ebeam"); hTotalEnergy1->GetYaxis()->SetTitle("Counts"); hTotalLightRel = new TH1F("Total_Light_rel","Relative Total light detected (energy equivalent)",1000,0.,1000.); hTotalLightRel->GetXaxis()->SetTitle("Energy/Ebeam"); hTotalLightRel->GetYaxis()->SetTitle("Counts"); hTotalLightRel2 = new TH1F("Total_Light_rel2","Relative Total light detected (energy equivalent)",55,0.,1.1); hTotalLightRel2->GetXaxis()->SetTitle("Energy/Ebeam"); hTotalLightRel2->GetYaxis()->SetTitle("Counts"); hTotalEnergyRel = new TH1F("Total_Energy_rel","Relative Total energy detected",5000,0.,5000); hTotalEnergyRel->GetXaxis()->SetTitle("Energy/Ebeam"); hTotalEnergyRel->GetYaxis()->SetTitle("Counts"); hParticle = new TH1F("Particle","PID of particle which produced the energy loss",3000,0.,3000.); hParticle->GetXaxis()->SetTitle("Particle ID"); hParticle->GetYaxis()->SetTitle("Counts"); hPaddleEnergy = new TH1F("PaddleEnergy","Energy deposit in one paddle",500,0.,100.); hPaddleEnergy->GetXaxis()->SetTitle("Energy (MeV)"); hPaddleEnergy->GetYaxis()->SetTitle("Counts"); hFirstEnergy = new TH1F("FirstEnergy","First energy deposit in a paddle",500,0.,100.); hFirstEnergy->GetXaxis()->SetTitle("Energy (MeV)"); hFirstEnergy->GetYaxis()->SetTitle("Counts"); hElossLight = new TH2F("ElossLight","Light quenching for protons",200,0.,1000.,200,0.,1000.); hElossLight->GetXaxis()->SetTitle("Energy (MeV)"); hElossLight->GetYaxis()->SetTitle("Light (MeV)"); if(npaddles<202){ //LAND detector hMult1 = new TH1F("Multiplicity1","Paddle multiplicity if two Pms have fired",20,-0.5,19.5); hMult1->GetXaxis()->SetTitle("Multiplicity"); hMult1->GetYaxis()->SetTitle("Counts"); hMult2 = new TH1F("Multiplicity2","Paddle multiplicity if one PM has fired",20,-0.5,19.5); hMult2->GetXaxis()->SetTitle("Multiplicity"); hMult2->GetYaxis()->SetTitle("Counts"); } else if(npaddles>202){ //Neuland detector hMult1 = new TH1F("Multiplicity1","Paddle multiplicity",100,0.,100.); hMult1->GetXaxis()->SetTitle("Multiplicity"); hMult1->GetYaxis()->SetTitle("Counts"); hMult2 = new TH1F("Multiplicity2","Paddle multiplicity",100,0.,100.); hMult2->GetXaxis()->SetTitle("Multiplicity"); hMult2->GetYaxis()->SetTitle("Counts"); } pc*/ return kSUCCESS; } // ------------------------------------------------------------------------- // ----- Public method Exec -------------------------------------------- void R3BCHIMERATreat::Exec(Option_t* opt) { cout<<"new event..............................."<GetEntries(); Int_t TrackId=0; Double_t ratio=0; for (Int_t l=0;lAt(l); // Int_t paddle = int(land_obj->GetSector())-1; //note that paddle starts at 1 // Int_t scint = int(land_obj->GetPaddleNb()); Double_t eloss = chimera_obj->GetEnergyLoss()*1000.; Double_t light = chimera_obj->GetLightYield()*1000.; Double_t slow = chimera_obj->GetSlow()*1000.; Double_t xIn = chimera_obj->GetXIn(); Double_t yIn = chimera_obj->GetYIn(); Double_t zIn = chimera_obj->GetZIn(); Double_t xOut = chimera_obj->GetXOut(); Double_t yOut = chimera_obj->GetYOut(); Double_t zOut = chimera_obj->GetZOut(); Double_t time = chimera_obj->GetTime(); Int_t detID = chimera_obj->GetDetectorID(); // Int_t media = int(land_obj->GetPaddleType()); TrackId = chimera_obj->GetTrackID(); R3BMCTrack *aTrack = (R3BMCTrack*) fChimeraMCTrack->At(TrackId); Int_t PID = aTrack->GetPdgCode(); Int_t mother = aTrack->GetMotherId(); // cout <<" TrackId " << TrackId << " PID = "<< PID << " mother = " << mother << // " ELoss " << eloss << " light " << light <<" slow " << slow <<" detid = "<< detID; if(!gGeoManager) cout << " gGeoManager missing" << endl; gGeoManager->FindNode(xIn,yIn,zIn); TGeoNode* curNode = gGeoManager->GetCurrentNode(); Int_t ntel=curNode->GetNumber(); // cout << " " << curNode->GetNumber() <Gaus(light,light*0.001/2.35); dlight[ntel-144]=dlight[ntel-144]+lR; Double_t sR=gRandom->Gaus(slow,slow*0.001/2.35); dslow[ntel-144]=dslow[ntel-144]+sR; // cout << " " << ntel <<" "<1000020040)ratio=0.8; if(PID==1000020040)ratio=0.8; if(PID==1000020030)ratio=0.8; if(PID==1000010030)ratio=0.8; if(PID==1000010020)ratio=0.8; if(PID==2212)ratio=0.8; if(PID==22)ratio=0.8; // dslow[ntel] =dslow[ntel] +5*(light-eloss*ratio); // cout << gMC->TrackCharge()<201){ //NeuLAND detector timeRes = 0.15;//ns } // light attenuation of plastic scintillator // att = 0.005; // in [1/cm] att = 0.008; // in [1/cm] // decay constant of BC408 scintillator // Double_t lambda=0.693147/2.5; // in [1/ns] This lambda is actually a t1/2 // Double_t lambda=1./3.1; // in [1/ns] Double_t lambda=1./2.1; // in [1/ns] // half of the length of a scintillator plength = fLandDigiPar->GetPaddleLength(); // in [cm] // length of time gate for QDC Double_t tofRange = 400.;//in [ns] // energy calibration factor // calFactor=0.6; calFactor=0.4; // Individual thresholds for PM's Double_t thresh[npaddles]; for (Int_t i=0;iRndm(0)-0.5)*0.15; // here one has the possibility to assign individual thresholds thresh[i] = 0.16+ran; // [MeV] for geant4 } //**************************************************** Int_t nentries = fLandPoints->GetEntries(); Int_t PMmult[npaddles]; Double_t QDC[npaddles],TDC[npaddles]; Double_t QDC_temp[npaddles],TDC_temp[npaddles]; Double_t TotalEnergy; Double_t TotalEnergyLee; Double_t TotalLight = 0; Int_t mult1=0; Int_t mult2=0; Int_t TrackId=0; Double_t xpos[npaddles],ypos[npaddles],zpos[npaddles]; Double_t xpos_temp[npaddles],ypos_temp[npaddles],zpos_temp[npaddles]; Double_t beta,gamma,pnx,pny,pnz,pnzcm,p,betaNeut,betaFrag,gammaNeut,gammaFrag; Double_t E_lab; Double_t xpaddle[npaddles],ypaddle[npaddles],zpaddle[npaddles]; Int_t PDG; Double_t en,s,rr; // reset TotalEnergy=0.; TotalEnergyLee=0.; for (Int_t j=0;jAt(l); Int_t paddle = int(land_obj->GetSector())-1; //note that paddle starts at 1 Int_t scint = int(land_obj->GetPaddleNb()); Double_t eloss = land_obj->GetEnergyLoss()*1000.*calFactor; Double_t light = land_obj->GetLightYield()*1000.*calFactor; Double_t xIn = land_obj->GetXIn(); Double_t yIn = land_obj->GetYIn(); Double_t zIn = land_obj->GetZIn(); Double_t xOut = land_obj->GetXOut(); Double_t yOut = land_obj->GetYOut(); Double_t zOut = land_obj->GetZOut(); Double_t time = land_obj->GetTime(); Int_t media = int(land_obj->GetPaddleType()); TrackId = land_obj->GetTrackID(); R3BMCTrack *aTrack = (R3BMCTrack*) fLandMCTrack->At(TrackId); Int_t PID = aTrack->GetPdgCode(); // Double_t x = (xIn+xOut)/2.; // Double_t y = (yIn+yOut)/2.; // Double_t z = (zIn+zOut)/2.; Double_t x = xIn; Double_t y = yIn; Double_t z = zIn; if (eloss > 0. && media == 3) { TotalEnergy+=eloss; TotalEnergyLee+=light; } Int_t mother = aTrack->GetMotherId(); if(1>2){ cout<< "entry "< 0. && media == 3) { // store Particle ID which caused the energy loss if(eloss > 1.) hParticle->Fill(PID,1.); PMmult[paddle] = PMmult[paddle] + 1; Int_t m = PMmult[paddle]; // cout << "multi per paddle: "<1500) { cout<<"Too many hits in one paddle: "<< m<< " hits"<FindNode(x,y,z); TGeoNode* curNode = gGeoManager->GetCurrentNode(); gGeoManager->CdUp(); TGeoNode* curNode1 = gGeoManager->GetCurrentNode(); //cout << "Node: " << curNode1->GetName() << " " << paddle << endl; Double_t local_point[3]; Double_t global_point[3]; local_point[0]=0.; local_point[1]=0.; local_point[2]=0.; gGeoManager->LocalToMaster(local_point, global_point); // cout<<"test "<< global_point[0] << " " << global_point[1] << // " " << global_point[2] << endl; xpaddle[paddle] = global_point[0]; ypaddle[paddle] = global_point[1]; zpaddle[paddle] = global_point[2]; // identify x and y paddles and calculate light transmission to the PM's // first plane are horizontal paddles // cout<<"paddle "< (npaddles-1)/2) { if((int)(((paddle-1)/paddle_per_plane))/2.==(int)((int)(((paddle-1)/paddle_per_plane))/2.)){ // horizontal paddles PM_res[paddle][m].Ltime = time+(plength-x)/cMedia; PM_res[paddle][m].LlightCFD = light*exp(-att*(plength-x)); PM_res[paddle][m].LlightQDC = light*exp(-att*(plength-x)); PM_res[paddle][m].Rtime = time+(plength+x)/cMedia; PM_res[paddle][m].RlightCFD = light*exp(-att*(plength+x)); PM_res[paddle][m].RlightQDC = light*exp(-att*(plength+x)); // cout<<"horizontal paddle "<< PM_res[paddle][m].LlightCFD<< // " "<Fill(TotalEnergy,TotalEnergyLee,1.); hTotalEnergy->Fill(TotalEnergy); hTotalEnergy1->Fill(TotalEnergy/calFactor/fBeamEnergy); hTotalLightRel->Fill(TotalEnergyLee); hTotalLight1->Fill(TotalEnergyLee/calFactor/fBeamEnergy); hTotalEnergyRel->Fill(TotalEnergy); // cout << "-I- R3BCHIMERATreat : energy=" << TotalEnergy << ", light=" << TotalEnergyLee << "." << endl; // Check for leading edge Double_t triggerTime=1e10; for(Int_t i = 0; i < npaddles; i++) { for (Int_t j = 0; j < PMmult[i]; j++) { PM_res[i][j+1].Lenergy=lambda*PM_res[i][j+1].LlightCFD; PM_res[i][j+1].Lenergy=PM_res[i][j+1].Lenergy+PM_res[i][j].Lenergy* exp(-lambda*(PM_res[i][j+1].Ltime-PM_res[i][j].Ltime)); if(PM_res[i][j+1].Lenergy > thresh[i]) { if(PM_res[i][j+1].Ltime < triggerTime) { triggerTime = PM_res[i][j+1].Ltime; }// find minimum }// if above threshold PM_res[i][j+1].Renergy=lambda*PM_res[i][j+1].RlightCFD; PM_res[i][j+1].Renergy=PM_res[i][j+1].Renergy+PM_res[i][j].Renergy* exp(-lambda*(PM_res[i][j+1].Rtime-PM_res[i][j].Rtime)); if(PM_res[i][j+1].Renergy > thresh[i]) { if(PM_res[i][j+1].Rtime < triggerTime) { triggerTime = PM_res[i][j+1].Rtime; }// find minimum }// if above threshold }// digis }// paddles // cout << "-I- R3BCHIMERATreat : triggerTime=" << triggerTime << "." << endl; Double_t temp[1500][3]; for (Int_t i=0;ithresh[i] && multl==0) { // if (triggerTime==0.) triggerTime=PM_res[i][j+1].Ltime; // This is supposed to mimic a QDC and a TDC // check if light is larger than threshold and register time // Take also time resolution of sigma=timeRes ps into account Double_t num=gRandom->Gaus(0.,timeRes); tofl=PM_res[i][j+1].Ltime+num; multl=multl+1; lightl=0.; for(Int_t k=1;k<=PMmult[i];k++){ // add all times inside +- tofRange (ns) for QDC if(TMath::Abs(PM_res[i][k].Ltime-triggerTime+tofRange/2.) < tofRange) { lightl=lightl+PM_res[i][k].LlightQDC; if(i<68){ // control histograms hPMl ->Fill(PM_res[i][k].Ltime,PM_res[i][k].LlightCFD); } } } } // PM_res[i][j+1].Renergy=lambda*PM_res[i][j+1].RlightCFD; if(PM_res[i][j+1].Renergy>thresh[i] && multr==0) { // if (triggerTime==0.) triggerTime=PM_res[i][j+1].Rtime; // This is supposed to mimic a QDC and a TDC // check if light is larger than threshold and register time // Take also time resolution of sigma=timeRes ps into account Double_t num=gRandom->Gaus(0.,timeRes); tofr=PM_res[i][j+1].Rtime+num; multr=multr+1; lightr=0.; for(Int_t k=1;k<=PMmult[i];k++){ // add all times inside +- tofRange (ns) for QDC if(TMath::Abs(PM_res[i][k].Rtime-triggerTime+tofRange/2.) < tofRange) { lightr=lightr+PM_res[i][k].RlightQDC; if(i<68){ // control histograms hPMr ->Fill(PM_res[i][k].Rtime,PM_res[i][k].RlightCFD); } } } } } // Multiplicity if only one PM has fired if(multl>0 || multr>0) mult2=mult2+1; if(multl>0 && multr>0){ //multiplicity if 2 PM's have fired mult1=mult1+1; // cout << "light l and r " << lightl<<" "< (npaddles-1)/2) { if((int)(((i-1)/paddle_per_plane))/2.==(int)((int)(((i-1)/paddle_per_plane))/2.)){ //horizontal paddles xpos_temp[mult1] = (tofr - tofl)/2.*cMedia; ypos_temp[mult1] = ypaddle[i]; zpos_temp[mult1] = zpaddle[i]; // cout << "delta tof x " << (tofl - tofr) << endl; } else { // vertical paddles xpos_temp[mult1] = xpaddle[i]; ypos_temp[mult1] = (tofr - tofl)/2.*cMedia; zpos_temp[mult1] = zpaddle[i]; // cout << "delta tof y " << (tofl - tofr) << endl; } // Here is an example how to fill the R3BLandDigi structure Double_t tdcL = tofl; Double_t tdcR = tofr; Double_t qdcL = lightl; Double_t qdcR = lightr; Int_t paddleNr = i+1; Double_t qdc=QDC_temp[mult1]; Double_t tdc=TDC_temp[mult1]; Double_t xx=xpos_temp[mult1]; Double_t yy=ypos_temp[mult1]; Double_t zz=zpos_temp[mult1]; // calling AddHit function will create a object // R3BLandDigi in memory and will automatically // add it to the array // sothat : 1 call to AddHit() 1 object in array // n calls to AddHit() n object in array AddHit(paddleNr, tdcL, tdcR, tdc, qdcL, qdcR, qdc, xx, yy, zz); } else { // recover hits with partial information } } // loop over paddles // cout << "multiplicity " << mult1 << endl; // sort final hits for time again TotalLight=0.; for (Int_t i=1;iFill(QDC[i],1.); TotalLight=TotalLight+QDC[i]; } // cout << "-I- R3BCHIMERATreat : totalLight=" << TotalLight << "." << endl; // control histograms if(mult2>0){ hMult2 ->Fill(mult2,1.); } hMult1 ->Fill(mult1,1.); hTotalLight->Fill(TotalLight,1.); hTotalLightRel2->Fill(TotalLight/200.,1.); hFirstEnergy->Fill(QDC[1],1.); if(fVerbose) { cout << "-I- R3BCHIMERATreat : produced " << fLandDigi->GetEntries() << " digis." << endl; }pc*/ hLight->Fill(dlight[30]); hEnergy->Fill(de[30]); hLightEnergy->Fill(de[30],dlight[30],1.); hFS->Fill(dslow[30],dlight[30],1.); hLight2->Fill(dlight[35]); hEnergy2->Fill(de[35]); hLightEnergy2->Fill(de[35],dlight[35],1.); hFS2->Fill(dslow[35],dlight[35],1.); hLight3->Fill(dlight[0]); hEnergy3->Fill(de[0]); hLightEnergy3->Fill(de[0],dlight[0],1.); hFS3->Fill(dslow[0],dlight[0],1.); hLight4->Fill(dlight[5]); hEnergy4->Fill(de[5]); hLightEnergy4->Fill(de[5],dlight[5],1.); hFS4->Fill(dslow[5],dlight[5],1.); hLight5->Fill(dlight[10]); hEnergy5->Fill(de[10]); hLightEnergy5->Fill(de[10],dlight[10],1.); hFS5->Fill(dslow[10],dlight[10],1.); int ifired=0; for(int i=0;i<352;i++){ if(dslow[i]>800)dslow[i]=800; if(dlight[i]>1100)dlight[i]=1100; if(dslow[i]>0 && dlight[i]>0){ hFSTot->Fill(dslow[i],dlight[i],1.); fs->fast[ifired]=dlight[i]; fs->slow[ifired]=dslow[i]; fs->de[ifired]=de[i]; fs->numtel[ifired]=i; ifired++; } } fs->multi=ifired; } // ------------------------------------------------------------------------- void R3BCHIMERATreat::Reset(){ // Clear the structure // cout << " -I- Digit Reset() called " << endl; //pc if (fLandDigi ) fLandDigi->Clear(); } void R3BCHIMERATreat::Finish() { hLight->Write(); hEnergy->Write(); hLightEnergy->Write(); hFS->Write(); hLight2->Write(); hEnergy2->Write(); hLightEnergy2->Write(); hFS2->Write(); hLight3->Write(); hEnergy3->Write(); hLightEnergy3->Write(); hFS3->Write(); hLight4->Write(); hEnergy4->Write(); hLightEnergy4->Write(); hFS4->Write(); hLight5->Write(); hEnergy5->Write(); hLightEnergy5->Write(); hFS5->Write();hFSTot->Write(); // here event. write histos // cout << " -I- Digit Finish() called " << endl; // Write control histograms /*pc hPMl->Write(); hPMr->Write(); hMult1->Write(); hMult2->Write(); hParticle->Write(); hFirstEnergy->Write(); hPaddleEnergy->Write(); hTotalLight->Write(); hTotalLight1->Write(); hTotalEnergy->Write(); hTotalEnergy1->Write(); hTotalLightRel->Write(); hTotalLightRel2->Write(); hTotalEnergyRel->Write(); hElossLight->Write(); pc*/ } /*pcR3BLandDigi* R3BCHIMERATreat::AddHit(Int_t paddleNr, Double_t tdcL, Double_t tdcR, Double_t tdc, Double_t qdcL, Double_t qdcR, Double_t qdc, Double_t xx, Double_t yy, Double_t zz){ // It fills the R3BLandDigi array R3BLandDigi *digi = new((*fLandDigi)[fLandDigi->GetEntriesFast()]) R3BLandDigi(paddleNr,tdcL,tdcR,tdc,qdcL,qdcR,qdc,xx,yy,zz); return digi; }pc*/ ClassImp(R3BCHIMERATreat)