void example(double E0 = 50, int nevents = 100000) { TStopwatch timer; // compound nucleus = carbon KVNucleus CN(6, 12); CN.SetExcitEnergy(E0); // decay products KVEvent decay; KVNucleus* n = decay.AddParticle(); n->SetZandA(1, 2); n = decay.AddParticle(); n->SetZandA(2, 4); n = decay.AddParticle(); n->SetZandA(3, 6); MicroStat::mdweight gps; Double_t etot = E0 + decay.GetChannelQValue(); Double_t total_mass = decay.GetSum("GetMass"); if (etot <= 0) { printf("Break-up channel is not allowed\n"); return; } gps.SetWeight(&decay, etot); gps.initGenerateEvent(&decay); std::cout << "Edisp = " << etot << " MeV" << std::endl; KVHashList histos; TH1F* h; while ((n = decay.GetNextParticle())) { Double_t kappa = total_mass / (total_mass - n->GetMass()); std::cout << n->GetSymbol() << " : max KE = " << 1. / kappa << " * " << etot << " MeV" << std::endl; std::cout << n->GetSymbol() << " : m/M = " << n->GetMass() / total_mass << " k = " << kappa << std::endl; histos.Add(h = new TH1F(n->GetSymbol(), Form("Kinetic energy of %s", n->GetSymbol()), 200, 0, etot)); h->Sumw2(); } KVEvent event; while (nevents--) { gps.GenerateEvent(&decay, &event); while ((n = event.GetNextParticle()))((TH1F*)histos.FindObject(n->GetSymbol()))->Fill(n->GetE()); gps.resetGenerateEvent(); } TIter it(&histos); while ((h = (TH1F*)it())) { KVNucleus part(h->GetName()); new TCanvas; FitEDist(h, etot, decay.GetMult(), total_mass, part.GetMass()); } timer.Print(); }
void KVGeoImport::ImportGeometry(Double_t dTheta, Double_t dPhi, Double_t ThetaMin, Double_t PhiMin, Double_t ThetaMax, Double_t PhiMax) { // Scan the geometry in order to find all detectors and detector alignments. // This is done by sending out "particles" from (0,0,0) in all directions between // (ThetaMin,ThetaMax) - with respect to Z-axis - and (PhiMin,PhiMax) - cylindrical // angle in the (X,Y)-plane, over a grid of step dTheta in Theta and dPhi in Phi. KVEvent* evt = new KVEvent(); KVNucleus* nuc = evt->AddParticle(); nuc->SetZAandE(1,1,1); Double_t theta,phi; Int_t count=0; // note that ImportGeometry can be called for a KVMultiDetArray // which already contains detectors, groups and id telescopes fGroupNumber=fArray->GetStructureTypeList("GROUP")->GetEntries(); Int_t ndets0 = fArray->GetDetectors()->GetEntries(); Int_t idtels0 = fArray->GetListOfIDTelescopes()->GetEntries(); for(theta=ThetaMin; theta<=ThetaMax; theta+=dTheta){ for(phi=PhiMin; phi<=PhiMax; phi+=dPhi){ nuc->SetTheta(theta); nuc->SetPhi(phi); fCurrentGroup = 0; fLastDetector = 0; PropagateEvent(evt); count++; } } // make sure detector nodes are correct TIter next(fArray->GetDetectors()); KVDetector*d; while( (d=(KVDetector*)next()) ) d->GetNode()->RehashLists(); // set up all detector node trajectories //fArray->CalculateGeoNodeTrajectories(); if(fCreateArray){ fArray->SetGeometry(GetGeometry()); KVGeoNavigator* nav = fArray->GetNavigator(); nav->SetDetectorNameFormat(fDetNameFmt); for(register int i=0; i<fStrucNameFmt.GetEntries(); i++){ KVNamedParameter* fmt = fStrucNameFmt.GetParameter(i); nav->SetStructureNameFormat(fmt->GetName(), fmt->GetString()); } nav->SetNameCorrespondanceList(fDetStrucNameCorrespList); fArray->CalculateDetectorSegmentationIndex(); } Info("ImportGeometry", "Tested %d directions - Theta=[%f,%f:%f] Phi=[%f,%f:%f]",count,ThetaMin,ThetaMax,dTheta,PhiMin,PhiMax,dPhi); Info("ImportGeometry", "Imported %d detectors into array", fArray->GetDetectors()->GetEntries()-ndets0); if(fCreateArray){ fArray->CreateIDTelescopesInGroups(); Info("ImportGeometry", "Created %d identification telescopes in array", fArray->GetListOfIDTelescopes()->GetEntries()-idtels0); } }
void example(double E0 = 50, int nevents = 100000) { // 12C* -> 3(4He) // compound nucleus = carbon KVNucleus CN(6, 12); CN.SetExcitEnergy(E0); // decay products KVEvent decay; KVNucleus* n = decay.AddParticle(); n->SetZandA(2, 4); n = decay.AddParticle(); n->SetZandA(2, 4); n = decay.AddParticle(); n->SetZandA(2, 4); KVGenPhaseSpace gps; if (!gps.SetBreakUpChannel(CN, &decay)) { printf("Break-up channel is not allowed\n"); return; } TFile* out = new TFile("ThreeAlphaDecay.root", "recreate"); TTree* tri = new TTree("ThreeAlphaDecay", Form("12C(E*=%lf.2MeV) -> 3(4He)", E0)); Int_t mult; Double_t wgt; tri->Branch("mult", &mult); tri->Branch("wgt", &wgt); AddArrBrI(Int_t, Z); AddArrBrI(Int_t, A); AddArrBrD(Double_t, E); AddArrBrD(Double_t, Theta); AddArrBrD(Double_t, Phi); while (nevents--) { wgt = gps.Generate(); decay.FillArraysEThetaPhi(mult, Z, A, E, Theta, Phi); tri->Fill(); } out->Write(); delete out; }
void example(double E0 = 50, int nevents = 100000) { TStopwatch timer; // 12C* -> 3(4He) // compound nucleus = carbon KVNucleus CN(6, 12); CN.SetExcitEnergy(E0); // decay products KVEvent decay; KVNucleus* n = decay.AddParticle(); n->SetZandA(2, 4); n = decay.AddParticle(); n->SetZandA(2, 4); n = decay.AddParticle(); n->SetZandA(2, 4); MicroStat::mdweight gps; Double_t etot = E0 + decay.GetChannelQValue(); if (etot <= 0) { printf("Break-up channel is not allowed\n"); return; } gps.SetWeight(&decay, etot); gps.initGenerateEvent(&decay); TH1F* h1 = new TH1F("h1", "Kinetic energy of alpha particle 3", 200, 0, etot * 2. / 3.); h1->Sumw2(); KVEvent event; while (nevents--) { gps.GenerateEvent(&decay, &event); h1->Fill(event.GetParticle(3)->GetKE()); gps.resetGenerateEvent(); } h1->Draw(); TF1* EDis = new TF1("EDis", edist, 0., etot, 3); EDis->SetNpx(500); EDis->SetParLimits(0, 0, 1.e+08); EDis->SetParLimits(1, 0, 2 * etot); EDis->FixParameter(2, 3); gStyle->SetOptFit(1); h1->Fit(EDis, "EM"); timer.Print(); }
void KVINDRA::CreateROOTGeometry() { // Overrides KVASMultiDetArray::CreateGeoManager in order to use INDRAGeometryBuilder // which builds the TGeo representation of INDRA using the Y. Huguet CAO data. // // The optional arguments (dx,dy,dz) are the half-lengths in centimetres of the "world"/"top" volume // into which all the detectors of the array are placed. This should be big enough so that all detectors // fit in. The default values of 500 give a "world" which is a cube 1000cmx1000cmx1000cm (with sides // going from -500cm to +500cm on each axis). // // If closegeo=kFALSE we leave the geometry open for other structures to be added. if (!IsBuilt()) { Error("CreateROOTGeometry", "gIndra has to be build first"); return; } if (!GetNavigator()) { //Error("CreateROOTGeometry","No existing navigator"); return; SetNavigator(new KVRangeTableGeoNavigator(gGeoManager, KVMaterial::GetRangeTable())); GetNavigator()->SetNameCorrespondanceList("INDRA.names"); } // set up shape & matrix pointers in detectors Info("CreateROOTGeometry", "Scanning geometry shapes and matrices..."); KVGeoImport gimp(gGeoManager, KVMaterial::GetRangeTable(), this, kFALSE); gimp.SetNameCorrespondanceList("INDRA.names"); KVEvent* evt = new KVEvent(); KVNucleus* nuc = evt->AddParticle(); nuc->SetZAandE(1, 1, 1); KVINDRADetector* det; TIter next(GetDetectors()); Int_t nrootgeo = 0; while ((det = (KVINDRADetector*)next())) { nuc->SetTheta(det->GetTheta()); nuc->SetPhi(det->GetPhi()); gimp.SetLastDetector(0); gimp.PropagateEvent(evt); if (!(det->GetActiveLayerShape() && det->GetActiveLayerMatrix())) { Info("CreateROOTGeometry", "Volume checking for %s", det->GetName()); Double_t theta0 = det->GetTheta(); Double_t phi0 = det->GetPhi(); for (Double_t TH = theta0 - 0.5; TH <= theta0 + 0.5; TH += 0.1) { for (Double_t PH = phi0 - 10; PH <= phi0 + 10; PH += 1) { nuc->SetTheta(TH); nuc->SetPhi(PH); gimp.SetLastDetector(0); gimp.PropagateEvent(evt); if (det->GetActiveLayerShape() && det->GetActiveLayerMatrix()) break; } if (det->GetActiveLayerShape() && det->GetActiveLayerMatrix()) break; } } if (!(det->GetActiveLayerShape() && det->GetActiveLayerMatrix())) { Info("CreateROOTGeometry", "Volume checking failed for : %s", det->GetName()); } // check etalon trajectories (if etalons are present) if (det->GetActiveLayerShape() && det->GetActiveLayerMatrix() && det->GetRingNumber() > 9) { if (GetDetector(Form("SI75_%d", det->GetRingNumber())) || GetDetector(Form("SILI_%d", det->GetRingNumber()))) { if ((det->IsCalled("CSI_1002") || det->IsCalled("CSI_1102") || det->IsCalled("CSI_1202") || det->IsCalled("CSI_1304") || det->IsCalled("CSI_1403") || det->IsCalled("CSI_1503") || det->IsCalled("CSI_1602") || det->IsCalled("CSI_1702")) && det->GetNode()->GetNDetsInFront() < 2) { Info("CreateROOTGeometry", "Trajectory checking for %s", det->GetName()); Double_t theta0 = det->GetTheta(); Double_t phi0 = det->GetPhi(); for (Double_t TH = theta0 - 0.5; TH <= theta0 + 0.5; TH += 0.1) { for (Double_t PH = phi0 - 10; PH <= phi0 + 10; PH += 1) { nuc->SetTheta(TH); nuc->SetPhi(PH); gimp.SetLastDetector(0); gimp.PropagateEvent(evt); if (det->GetNode()->GetNDetsInFront() == 2) break; } if (det->GetNode()->GetNDetsInFront() == 2) break; } } } } nrootgeo += (det->GetActiveLayerShape() && det->GetActiveLayerMatrix()); } delete evt; Info("CreateROOTGeometry", "ROOT geometry initialised for %d/%d detectors", nrootgeo, GetDetectors()->GetEntries()); // Set up trajectories TIter it(GetDetectors()); KVDetector* d; while ((d = (KVDetector*)it())) d->GetNode()->RehashLists();// make sure detector nodes are correct AssociateTrajectoriesAndNodes(); DeduceGroupsFromTrajectories(); FillTrajectoryIDTelescopeLists(); CalculateReconstructionTrajectories(); GetNavigator()->AbsorbDetectorPaths(&gimp); }