///////////////////////////////////////////////////////////////// // Gen_Flasher.cc // Contact person: Eric Marzec // See Gen_Flasher.hh for more details ///////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; namespace RAT { Gen_Flasher::Gen_Flasher() : GLG4Gen("flasher"),fStateStr(""), fconc_length(0.0),fconc_offset(0.0) { // Set vertex generator to Flasher fVertexGen = new VertexGen_Flasher(); // Default time generator fTimeGen = new GLG4TimeGen_Poisson(); // Default to no poisson fluctuations of number of photons per pulse fPoisson = false; } void Gen_Flasher::FillTables() { // Get position and direction for "normal" PMTs // These arrays should be in LCN order. DBLinkPtr lPMTINFO = DB::Get()->GetLink("PMTINFO"); vector pmtx_DB = lPMTINFO->GetDArray("x"); vector pmty_DB = lPMTINFO->GetDArray("y"); vector pmtz_DB = lPMTINFO->GetDArray("z"); vector pmtu_DB = lPMTINFO->GetDArray("u"); vector pmtv_DB = lPMTINFO->GetDArray("v"); vector pmtw_DB = lPMTINFO->GetDArray("w"); vector pmttype_DB = lPMTINFO->GetIArray("pmt_type"); const DU::ChanHWStatus& ChanHWStatus = DU::Utility::Get()->GetChanHWStatus(); G4int size = pmtx_DB.size(); for(G4int i=0;iGetLink("CONCENTRATOR","cRAT"); fconc_length = lCONC->GetDArray("z_coord").back(); fconc_offset = lCONC->GetD("offset"); // Get PMT geometry DBLinkPtr lPMT = DB::Get()->GetLink("PMT","r1408"); fpmt_depth = lPMT->GetDArray("z_edge")[6]; fpmt_dynode_radius = lPMT->GetD("dynode_radius"); } Gen_Flasher::~Gen_Flasher() { } void Gen_Flasher::BeginOfRun() { GLG4Gen::BeginOfRun(); FillTables(); debug << "Gen_Flasher::BeginOfRun : Completed." << newline; } void Gen_Flasher::GenerateEvent( G4Event *event ) { debug << "Gen_Flasher::GenerateEvent: Generating Flasher events with top level generator\n"; G4double t0 = NextTime(); // Choose random PMT from the list of valid, flashable tubes long inum = CLHEP::RandFlat::shootInt(fpmtx.size()); G4double x = fpmtx[inum]; G4double y = fpmty[inum]; G4double z = fpmtz[inum]; G4double u = fpmtu[inum]; G4double v = fpmtv[inum]; G4double w = fpmtw[inum]; // Set PMT positions G4ThreeVector pos; pos.setX(x); pos.setY(y); pos.setZ(z); // Set PMT directions G4ThreeVector direction; direction.setX(u); direction.setY(v); direction.setZ(w); // Calculate off-axis position to put at side of PMT dynode G4ThreeVector perp = direction.orthogonal().unit(); double phi = CLHEP::twopi * G4UniformRand(); perp.rotate(phi, direction); perp.setMag(fpmt_dynode_radius + 5.0); // Adjust vertex position pos = pos + perp + (fconc_length+fconc_offset-fpmt_depth-10.0)*direction; debug << "Gen_Flasher: time = " << t0 << " position = (" << pos.x() << ", " << pos.y() << ", " << pos.z() << ")\n"; // Reverse direction so photons travel out of PMT direction = -direction; // Generate event dynamic_cast(fVertexGen)->SetDirection(direction); dynamic_cast(fVertexGen)->GeneratePrimaryVertex(event, pos, t0); } void Gen_Flasher::ResetTime( G4double offset ) { fNextTime = fTimeGen->GenerateEventTime() + offset; } void Gen_Flasher::SetState( G4String /*state*/ ) { // Can't set state here yet } G4String Gen_Flasher::GetState() const { return fStateStr; } void Gen_Flasher::SetTimeGen( G4String state ) { try { delete fTimeGen; fTimeGen = 0; // In case of exception in next line fTimeGen = RAT::GlobalFactory::New(state); info << "Gen_Flasher::SetTimeGen: Setting Flasher time generator to " << state << "\n"; } catch ( RAT::FactoryUnknownID &unknown ) { warn << "Gen_Flasher: Unknown time generator \"" << unknown.id << "\"" << newline; } } void Gen_Flasher::SetTimeState( G4String state ) { if (fTimeGen){ fTimeGen->SetState(state); }else{ warn << "Gen_Flasher::SetTimeState error: Cannot set time state, no time generator selected" << newline; } } G4String Gen_Flasher::GetTimeState() const { if (fTimeGen) return fTimeGen->GetState(); else return G4String("Gen_Flasher::GetTimeStat error: no time generator selected"); } void Gen_Flasher::SetVertexState( G4String /*state*/ ) { warn << "Gen_Flasher::SetVertexState error: Cannot set vertex state - fixed to VertexGen_Flasher" << newline; } G4String Gen_Flasher::GetVertexState() const { return G4String("Gen_Flasher::GetVertexState: vertex generator fixed to VertexGen_Flasher"); } void Gen_Flasher::SetPosState( G4String /*state*/ ) { warn << "Gen_Flasher::SetPosState error: Cannot set position state" << newline; } G4String Gen_Flasher::GetPosState() const { return G4String("Gen_Flasher::GetPosState: position state fixed"); } void Gen_Flasher::SetPoissonFluctuations( G4bool set ) { fPoisson = set; if(fPoisson){ info << "Gen_Flasher::SetPoissonFluctuations: Poisson fluctuation number of photons per pulse " <<"\n"; }else{ info << "Gen_Flasher::SetPoissonFluctuations: Fixing number of photons per pulse \n"; } } } // namespace RAT