Developing #57
Генератор коктейля ионов ERIonMixGenerator
Status: | Закрыта | Start date: | 06/29/2017 | |
---|---|---|---|---|
Priority: | Низкий | Due date: | ||
Assignee: | Mikhail Kozlov | % Done: | 0% | |
Category: | BeamDet | |||
Target version: | v-0.4 |
Description
В мишень попадает коктейль из ионов разного типа. Для идентификации какой именно ион прилетел в мишень используется BeamDet. Для симуляции работы BeamDet необходимо разработать генератор событий который будет создавать события с разными ионами в зависимости от вероятности их появления.
Рабочее название для генератора ERШonMixGenerator. Он должен обладать всеми интерфейсами ERIonGenerator (Уметь испускть ион с размазанной координатой и импульсом) и соответсвнно быть наследован от него.
Конструктор ERIonGenerator имеет следующие параметры: ERIonGenerator(TString name, Int_t z, Int_t a, Int_t q, Int_t mult), Будем считать, что конструктор задает главный ион генератора - события с которым нам интересны. В события с этим ионом должны быть подмешаны события с ионами фона. Для этого необходимо завести интерфейс AddBackgroundIon(name,z,a,q,probability). Вероятность главного иона будет расчитываться как 1 - сумма вероятностей фоновы ионов. Характер размазвания вершины и импульса для фоновых ионов такой же как для главного.
Необходимо перегрузить ERIonGenerator::ReadEvent(). При этом желательно не копипастить код из него реализующий размазвание, а переработать его, выделив в отдельную функцию и отнаследовав.
History
#1 Updated by Vitaliy Schetinin over 7 years ago
- Assignee changed from Vitaliy Schetinin to Mikhail Kozlov
#2 Updated by Mikhail Kozlov over 7 years ago
1) Не могу решить как лучше хранить вероятность появления разных ионов и как потом это использовать в ReadEvent.
2) Не совсем понимаю, что делать с ReadEvent. Нужно ли менять его код в ERIonGenerator или просто перегрузить в ERIonMixGenerator? И что при этом выносить в отдельную функцию - ту часть которая внутри цикла по количеству ионов в событий?
#3 Updated by Vitaliy Schetinin over 7 years ago
1) Хранить как атрибут класса типа std::map(name, probability) fBGIons. Вся информация по иону будет доступна в TPDGDatabase после run->AddNewIon(fIon);
2) В AddBackgroundIon() надо добавить проверку, что в сумме по вероятностям мы не вылетели за 1.
3) В отдельную функцию я бы предложил вынести розыгрыш координаты и импульса:
phi = gRandom->Uniform(fPhiMin,fPhiMax) * TMath::DegToRad(); if (fPRangeIsSet ) { pabs = gRandom->Uniform(fPMin,fPMax); } else if (fPtRangeIsSet) { pt = gRandom->Uniform(fPtMin,fPtMax); } if (fThetaRangeIsSet) { if (fCosThetaIsSet) theta = acos(gRandom->Uniform(cos(fThetaMin* TMath::DegToRad()), cos(fThetaMax* TMath::DegToRad()))); else { theta = gRandom->Uniform(fThetaMin,fThetaMax) * TMath::DegToRad(); } } else if (fEtaRangeIsSet) { eta = gRandom->Uniform(fEtaMin,fEtaMax); theta = 2*TMath::ATan(TMath::Exp(-eta)); } else if (fYRangeIsSet) { y = gRandom->Uniform(fYMin,fYMax); mt = TMath::Sqrt(fPDGMass*fPDGMass + pt*pt); pz = mt * TMath::SinH(y); } if (fThetaRangeIsSet || fEtaRangeIsSet) { if (fPRangeIsSet ) { pz = pabs*TMath::Cos(theta); pt = pabs*TMath::Sin(theta); } else if (fPtRangeIsSet) { pz = pt/TMath::Tan(theta); } } px = pt*TMath::Cos(phi); py = pt*TMath::Sin(phi); if (fBoxVtxIsSet) { fX = gRandom->Uniform(fX1,fX2); fY = gRandom->Uniform(fY1,fY2); }
В перегруженном ReadEvent() надо идти циклом по множественности ионов, разыгрывать с помощью функции вершину и ипульс, разыгрывать вероятность появления иона, по fBDIons определять какой именно ион, по его имени из базы доставать PDG код и ион стаким кодом, вершиной и импульсом добавлять в стек первичных треков.
#4 Updated by Mikhail Kozlov over 7 years ago
1) Сейчас AddBackgraondIon() работает так, что он по порядку помещает в map все ионы, пока суммарная вероятность не превышает 1. Например, если добавить ионы с вероятностями появления:
1) 0.5
2) 0.6
3) 0.1
4) 0.2
то будут генерироваться все, кроме второго.
2) Если добавить два вот таких иона:
sgenerator->AddBackgroundIon("BgIon1", 27, 9, 9, 0.3);
sgenerator->AddBackgroundIon("BgIon2", 3, 9, 3, 0.4);
то симуляця почему-то падает на 4 событии.
#5 Updated by Vitaliy Schetinin over 7 years ago
Она не просто падает. Она страдает и кидается сообщениями:
G4NucleiProperties::GetMassExccess: Wrong values for A = 9 and Z = 27 G4NucleiProperties::GetMassExccess: Wrong values for A = 9 and Z = 27 G4NucleiProperties::GetNuclearMass: Wrong values for A = 8 and Z = 26 G4NucleiProperties::GetMassExccess: Wrong values for A = 9 and Z = 27
Потому что A меньше Z. Чего быть не должно. A это массовое число = кол-во нейтронов + кол-во протонов в ядре. Z = количеству протонов
Q тоже ставь равным количеству протонов.
С такими параметрами у меня все взлетело:
sgenerator->AddBackgroundIon("BgIon1", 27, 36, 27, 0.5); sgenerator->AddBackgroundIon("BgIon2", 3, 12, 3, 0.3);
#6 Updated by Mikhail Kozlov over 7 years ago
Для Beamdet нужны следующие поправки:
1) Сделать не равномерное распределение координат в пространстве, а Гуассово для SetBoxXYZ() в генераторе. Сейчас размазывание находится в spreadingParameters.
Как лучше поступить? Можно вынести это дело в отдельную функцию и ее перегрузить в mix генераторе, либо прям в ERIonGenerator поменять Uniform на Gauss.
2) Кинетическую энергию тоже размазать по Гауссу. Вопросы теже, что в п.1.
#7 Updated by Vitaliy Schetinin over 7 years ago
1) Явно нужно делать два варианта и к ним два интерфеса: SetBoxXYZ() - работает как было. Set SetGausXYZ() - делает гаусово распредение. Какой интерфейс был пользователем вызван последним - ту логику и выбрать. Сначала надо реализовать в ERIonGenerator. Да лучше две функции иметь. Для разыгрывания по Uniform - та что есть и для разыгрывания по Гаусу. Потом их уже перегрузить в ERIonMixGenerator
2) Логика таже что в пунтке 1. Только давай уж конкретно займемся. У нас на данный момент интерфес только к импульсу. Поэтому в макросе пользователь пересчитывает. Это не удобно. Давай делать как для импульса так и для энергии и Гаусс и униформ
#8 Updated by Vitaliy Schetinin over 7 years ago
- Status changed from Открыта to Закрыта