/**VertexGen_UFO * contact person: Mark Stringer */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace CLHEP; using namespace std; namespace RAT { VertexGen_UFO::VertexGen_UFO(const char *arg_dbname) : GLG4VertexGen(arg_dbname) { // Not yet initialised - call the Init function to setup on first event fInitDB = false; } VertexGen_UFO::~VertexGen_UFO() { } void VertexGen_UFO::Init() { // This function should be run once on the first event (once DB all set up) warn << "VertexGen_UFO::Init: Initialising simulation settings \n"; // Photon definition (assume /run/initialize already done) fPhotonDef = G4ParticleTable::GetParticleTable()->FindParticle("opticalphoton"); // Load database values getting information about geometry of ufo first DBLinkPtr lUFO = DB::Get()->GetLink("UFOGEO"); fNleds = lUFO->GetI("n_leds"); fUFORadius = lUFO->GetD("radius"); //Use these values to generate the LED Positionsj double angularSpacing = twopi/fNleds; //FIRST LED FIRING WILL BE POINTING EAST for(int ledIter=0; ledIterGetLink("UFOLED"); info << "Loaded information about the UFO LED"<GetFArrayFromD("dist_wl"); fMaxWl = fwave.back(); fMinWl = fwave.front(); // make a check that the values in the dist_wl make sense and increase monotonically for(unsigned iv=1;ivGetFArrayFromD("dist_wl_intensity"); } catch(DBNotFoundError &e){ Log::Die("VertexGen_UFO::Init: can't find ratdb UFOLED dist_wl_intensity info"); } // now create a cumulative magnitude vector float wavemagsum = 0; fwaveCumMag.clear(); fwaveCumMag.push_back(0.0); info << " Cumulative wavelength "; for(unsigned int i=1;iGetI("intensity"); } catch(DBNotFoundError &e){ Log::Die("VertexGen_UFO::Init: cant find ratdb UFOLED intensity info"); } //Copied from VertexGen_Laserball try { string temp = lUFO->GetS("pulse_mode"); if(temp == "POISSON"||temp == "poisson"){ fPoisson = true; info << "VertexGen_UFO::Init: Setting pulse mode to poisson\n"; }else if(temp == "fixed" || temp == "FIXED"){ fPoisson = false; info << "VertexGen_UFO::Init: Setting pulse mode to fixed\n"; }else{ Log::Die(dformat("VertexGen_UFO::Init: UFO.pulse_mode = \"%s\" is invalid.", temp.c_str())); } } catch (DBNotFoundError &e) { }; //Now loading angle vector try{ fangle = lUFO->GetFArrayFromD("dist_angle"); } catch(DBNotFoundError &e){ Log::Die("VertexGen_UFO::Init: can't find ratdb UFOLED dist_angle info"); } //Now generating angular intensity array as lambertian fAngInt = GenerateLambertian(fangle); // now create a cumulative magnitude vector (Taken from VertexGen_Laserball) float anglemagsum = 0; fCumAngleDist.clear(); fCumAngleDist.push_back(0.0); info << " Cumulative Angle "; for(unsigned int i=1;iGetD("time_width"); } catch(DBNotFoundError &e){ Log::Die("VertexGen_UFO::Init: can't find ratdb UFOTIME time_width info"); } //Now loading the timing information of the UFO try{ lUFO = DB::Get()->GetLink("UFOTIME"); info << "Loaded information about the UFO TIMING"<GetD("rotation_time"); } catch(DBNotFoundError &e){ Log::Die("VertexGen_UFO::Init: can't find ratdb UFOTIME rotation_time info"); } //Initializing flash counter fLEDFlashCount = 0; try{ fFlashRate = lUFO->GetD("pulse_rate"); } catch(DBNotFoundError &e){ Log::Die("VertexGen_UFO::Init: can't find ratdb UFOTIME pulse_rate info"); } if(fFlashRate < 0){ Log::Die("VertexGen_UFO::Init please set UFOTIME pulse_rate to the generator rate"); } fFlashesPerRotation = fFlashRate*fRotationTime; // Should now be all initialised so set flag fInitDB = true; } void VertexGen_UFO::BeginOfRun() { Init(); } std::vector VertexGen_UFO::GenerateLambertian(std::vector angularDistribution){ std::vector output; double area = sin(angularDistribution.back())-sin(angularDistribution.front()); if(area == 0.0 || area == 0) area = 1.0; info << "AREA is: "< mydistx, std::vector mydistraw, std::vector mydistcum){ // Return value sampled from distribution with cumulative distribution mydistcum, raw distribution mydistraw for x points mydistx // (assume linear interpolation between specified points in spectrum) float start = mydistcum.front(); float stop = mydistcum.back(); // now throw a random number between these limits float random = start+G4UniformRand()*(stop-start); // now loop through cumulative distribution to choose energy int istep = 0; while(mydistcum[istep+1]= 1.0){ v1 = 2.0 * G4UniformRand() - 1.0; v2 = 2.0 * G4UniformRand() - 1.0; r = v1 * v1 + v2 * v2; } fac = v2 * sqrt( -2.0 * log( r ) / r ); return fac; } void VertexGen_UFO::GeneratePrimaryVertex(G4Event *event, G4ThreeVector &fPos0, G4double fTime0) { if (!fInitDB) Init(); // How many photons? int nphot = 0; if(fPoisson){ nphot = (G4int)( CLHEP::RandPoisson::shoot(fPhotonsPerEvent) ); }else{ nphot = fPhotonsPerEvent; } //Calculate which LED is firing int ledNumber = (int)((((double)(fLEDFlashCount%fFlashesPerRotation))/fFlashesPerRotation)*fNleds); fLEDFlashCount++; G4ThreeVector ledPos; for(int i=0; iSetPolarization(pol.x(), pol.y(), pol.z()); particle->SetMass(0.0); // Seems odd, but used in GLG4VertexGen_Gun vertex->SetPrimary(particle); event->AddPrimaryVertex(vertex); } } void VertexGen_UFO::SetState(G4String newValues) { Log::Die("SetState is deprecated, do not call it. Set all variables with /rat/db/set."); return; } G4String VertexGen_UFO::GetState() { stringstream result; result << "Photons per pulse: " <