Interactions ============ The *ER* has its own approach for adding interactions to the particle transport process. This approach is based on the ability of users to write their own *Stepping Action* for transport and the ability to add new tracks with defined properties to the *track stack*. It allows to take into account energy losses of projectiles in the beam diagnostics system and the target. This is a necessity in low energy physics simulations. Interaction position -------------------- We assume the exponential distribution of the interaction position along the trajectory of an ion inside the target. It could be true in the case of constant (energy independent) total interaction cross section. In reality we deal with a kind of approximation. The survival probability :math:`p_s` of an ion after passing the path :math:`x` is: .. math:: p_s=\exp(-x/\Lambda), where :math:`\Lambda` is the Nuclear Interaction Length. The interaction probability :math:`p_i=1-p_s`. One can reproduce uniform distribution of interactions in the target setting very large value of :math:`\Lambda`. The path :math:`l` of an ion passing without interaction through the target of an arbitrary convex shape along given trajectory depends on the position and orientation of the ion trajectory (scattering neglected). The longer is the :math:`l` the greater is the interaction probability for ions at the same trajectory. One can introduce so called maximum path length :math:`M` such that any ion in the simulation has the path inside the target less than this value. The Maximum path length is used for renormalization of the interaction probability for each trajectory: .. math:: R_i=\frac{1-\exp(\frac{-l}{\Lambda})}{1-\exp(\frac{-M}{\Lambda})}. Thus for the hypothetical trajectory with the maximum path length inside the target the interaction must happen (:math:`R_i=1`). Renormalization of the interaction probability allows to minimize the number of the ions sampled in MC preserving correct spatial distribution of the interaction points. In the picture below the target is black, the beam axis is magenta, the trajectory of an ion is orange, the maximum possible path of an ion in the target :math:`M` is green. The path inside the target is thick orange, it has the length :math:`l`. :math:`X` - is the interaction point. :math:`X_0` and :math:`X_0+l` - the points where the trajectory of the ion crosses the target boundary. .. figure:: _images/interaction_position.jpeg :scale: 60% :align: center The ion transport in the target is controlled by the following interfaces. * This value defines how steep is the exponential distribution of the interaction points inside the target along the trajectory: :: interaction->SetNuclearInteractionLength(20.); * The value which is greater than the path in the target for any possible ion: :: interaction->SetMaxPathLength(0.051); * Interaction should happen in following geometry volume: :: interaction->SetInteractionVolumeName("tubeD2"); * To control coordinate resolution one need to control max step of transport: :: interaction->SetMinStep(1e-5); * But for thick target one need to remember about limit of max step count (specified in g4Config.C) in volume: :: geant4->SetMaxNStep(30000); In the ER simulations the :math:`R_i` and :math:`X` are sampled for each incident ion, which is either transported by G4, undergoing EM interactions like energy loss and multiple scattering, till the interaction point (defined along the simulated trajectory) or killed. The 4-momentum of the ion in the interaction point is used for calculation of the reaction products' 4-momenta in the interaction point. On the user request transport of an incident ion till the given energy (for resonance reactions) and till the point distributed according to user defined tabulated distribution can be easily implemented. Elastic scattering ------------------ .. Ðвтозамены .. |empty| unicode:: U+2063 .. |theta| unicode:: U+03F4 .. |alpha| unicode:: U+03B1 .. |phi| unicode:: U+03C6 ПоÑтановка задачи упругого раÑÑеÑÐ½Ð¸Ñ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Ион **Ð** Ñ Ñнергией \ :sup:`A` \ **E**\ :sub:`0` , импульÑом \ :sup:`A` \ **P**\ :sub:`0` \(**P**\ :sub:`x` , **P**\ :sub:`y` , **P**\ :sub:`z` ), начальными проÑтранÑтвенными координатами \ :sup:`A` \ **r**\ :sub:`0` \(**x**\ :sub:`0` , **y**\ :sub:`0` , **z**\ :sub:`0` ) налетает на покоÑщуюÑÑ Ð¼Ð¸ÑˆÐµÐ½ÑŒ ÑоÑтоÑщую из атомов **B**. Ион **A** многократно раÑÑеиваетÑÑ Ð²Ð½ÑƒÑ‚Ñ€Ð¸ объёма мишени, на некотором шаге выбивает ион **B**, и далее уже оба иона многократно раÑÑеиваютÑÑ Ð¿Ð¾ÐºÐ° не покинут объем мишени. Ð’ результате - новые характериÑтики \ :sup:`A` \ **E**\, \ :sup:`A` \ **P(P**\ :sub:`x` , **P**\ :sub:`y` , **P**\ :sub:`z` ), \ :sup:`A` \ **r(x**, **y**, **z**)- Ð´Ð»Ñ Ð¸Ð¾Ð½Ð° **Ð**, и Ñледующие Ð´Ð»Ñ Ð¸Ð¾Ð½Ð° **B**: \ :sup:`B` \ **E**\, \ :sup:`B` \ **P(P**\ :sub:`x` , **P**\ :sub:`y` , **P**\ :sub:`z` ), \ :sup:`B` \ **r(x**, **y**, **z**). .. figure:: _images/elastic_fig1.png :height: 600px :width: 600 px :align: center РаÑÑмотрим Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ ÑƒÐ¿Ñ€ÑƒÐ³Ð¾Ð³Ð¾ раÑÑеÑÐ½Ð¸Ñ Ð² ÑеÑÑию ÑимулÑции на примере раÑÑеÑÐ½Ð¸Ñ Ð¸Ð¾Ð½Ð° 15N на мишени 11B. Создаем клаÑÑ ÐºÐ¾Ð»Ð»ÐµÐºÑ†Ð¸Ð¸ взаимодейÑтвий и клаÑÑ Ð²Ð·Ð°Ð¸Ð¼Ð¾Ð´ÐµÐ¹ÑтвиÑ:: ERDecayer* decayer = new ERDecayer(); ERElasticScattering* scattering = new ERElasticScattering("15Nto15N11B"); 15Nto15N11B - Ð˜Ð¼Ñ Ð²Ð·Ð°Ð¸Ð¼Ð¾Ð´ÐµÐ¹ÑтвиÑ. Входные данные ~~~~~~~~~~~~~~ Пользователь должен знать: #. Следующие характериÑтики ионов: * A - Ð°Ñ‚Ð¾Ð¼Ð½Ð°Ñ Ð¼Ð°ÑÑа * Z - чиÑло протонов * Q - зарÑд Ð”Ð»Ñ Ð½Ð°Ð»ÐµÑ‚Ð°ÑŽÑ‰ÐµÐ³Ð¾ иона, например Ð´Ð»Ñ \ :sup:`15` \N, данные характериÑтике задаютÑÑ Ñ‚Ð°Ðº:: scattering->SetInputIon(7,15,3); // Z = 7, A = 15, Q = 3 Ð Ð´Ð»Ñ Ð¸Ð¾Ð½Ð° мишени, например \ :sup:`11` \B так:: scattering->SetTargetIon(5,11,5); // Z = 5, A = 11, Q = 5 #. СпоÑоб Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ ÐºÐ¸Ð½ÐµÐ¼Ð°Ñ‚Ð¸Ñ‡ÐµÑких характериÑтик. По умолчанию, иÑпользуетÑÑ Ð¸Ð·Ð¾Ñ‚Ñ€Ð¾Ð¿Ð½Ð¾Ðµ раÑпределение угла раÑÑеÑÐ½Ð¸Ñ |theta|. Возможно задание кумулÑтивной функции раÑпределениÑ: Задаём Ð¸Ð¼Ñ Ñ‚ÐµÐºÑтового файла Ñ Ð´Ð°Ð½Ð½Ñ‹Ð¼Ð¸ о кумулÑтивной функции:: scattering->SetThetaCDF("cos_tetta_cross.txt"); Структура текÑтового файла должна быть ÑледующаÑ:: 4.5 0.0448573496944 4.6 0.087071447189 4.7 0.126858356665 4.8 0.164410246312 4.9 0.199891413123 5.0 0.233459173925 5.1 0.26523651571 5.2 0.295359837723 ... ... 179.3 0.99999999789 179.4 0.999999998493 179.5 0.999999998995 179.6 0.999999999397 179.7 0.999999999698 179.8 0.999999999899 179.9 1. 180.0 1. Где первый Ñтолбец ÑоответÑтвует углам |theta| в ÑиÑтеме центра маÑÑ, а второй — значениÑм кумулÑтивной функции Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ… значений углов |theta|. ТекÑтовый файл Ñ Ð´Ð°Ð½Ð½Ñ‹Ð¼Ð¸ о кумулÑтивной функции должен лежать в директории **er/input** . .. tip:: Формировнае кумулÑтивной функции на оÑнове теоретичеÑкой кривой оÑущеÑвлÑетÑÑ Ð² любой программе Ð´Ð»Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ Ñ Ñлектронными таблицами. .. figure:: _images/elastic_fig2.png :height: 600px :width: 600 px :align: center #. СпоÑоб Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ ÐºÐ¾Ð¾Ñ€Ð´Ð¸Ð½Ð°Ñ‚Ñ‹ взаимодейÑтвиÑ. * Ð”Ð»Ñ Ð¸Ð·Ð¾Ñ‚Ñ€Ð¾Ð¿Ð½Ð¾Ð³Ð¾ розыгрыша координаты взаимодейÑÑ‚Ð²Ð¸Ñ Ð²Ð½ÑƒÑ‚Ñ€Ð¸ объёма мишени. Задать переднюю координату мишени и заднюю отноÑительно глобальной оÑи **z**: :: scattering->SetUniformPos(-0.00035,0.00035); .. tip:: ИÑпользовать в Ñлучае **тонкой** мишени. .. figure:: _images/elastic_fig3.png :height: 600px :width: 600 px :align: center Обычно мишень раÑполагаетÑÑ Ð² начале глобальной ÑиÑтемы координат, данный риÑунок иллюÑтрирует Ñтот Ñлучай. * Ð”Ð»Ñ ÑкÑпоненциального розыгрыша координаты взаимодейÑтвиÑ, иÑпользуйте метод:: SetExponentialPos(Double_t start, Double_t tau); .. tip:: ИÑпользовать в Ñлучае **толÑтой** мишени. #. ТочноÑÑ‚ÑŒ необходимую Ð´Ð»Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ðµ координаты взаимодейÑтвиÑ. Ð”Ð»Ñ Ñтого задаем шаг пророгации внутри объёма мишени:: scattering->SetStep(0.00001); //0.1 micron #. СпоÑоб выбора диапазона розыгрыша углов |theta|\ :sub:`CM` и |phi|\ :sub:`CM` Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¸Ñ€Ð°ÐµÐ¼Ð¾Ð¹ чаÑтицы. По умолчанию |theta|\ :sub:`CM` разыгрываетÑÑ Ð²Ð½ÑƒÑ‚Ñ€Ð¸ диапазона от 0\ :sup:`0` до 180\ :sup:`0` ,а |phi|\ :sub:`CM` от 0\ :sup:`0` до 360\ :sup:`0` . ЕÑли же Ñтоит задача Ð¸Ð·Ð¼ÐµÑ€ÐµÐ½Ð¸Ñ ÑффективноÑти (Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ Ñигнала к фону) отдельно ÑтоÑщего детектора, а не целого ÑкÑпериментального Ñетапа, Ñтоит ограничить диапазон углов (ÑоответÑтвующий телеÑному углу, под которым виден детектор), чтобы не Ñимулировать большое чиÑло Ñобытий, когда большее чиÑло продуктов реакции не попадают в детектор. * Выбрать диапазон розыгрыша |theta|\ :sub:`CM` можно: #. Явно:: scattering->SetThetaRange(18.4, 19.4, kPROJECTILE, relMod = kFALSE); #. КоÑвенно. Через Ñледующие величины: * Координату |theta|\ :sub:`Lab` \ центра диапазона розыгрыша. * *Полуширину* выбираемого диапазона 0.5*d |theta| в лабораторной ÑиÑтеме координат:: scattering->SetLabThetaRange(thetaCenter, dTheta, kPROJECTILE, kTRUE, 0.); .. attention:: Важно выбирать полуширину Ñ Ð·Ð°Ð¿Ð°Ñом! Ðто значит, что нужно подбирать диапазон так, чтобы его дальнейшее увеличение не приводило к роÑту чиÑла зарегиÑтрированных Ñобытий. Ð’ обоих ÑлучаÑÑ… третьим параметром нужно передать Ñимулируемую чаÑтицу, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð±ÑƒÐ´ÐµÑ‚ лететь в детектор. Ðтой чаÑтицей может быть: * **kPROJECTILE** - Ð½Ð°Ð»ÐµÑ‚Ð°ÑŽÑ‰Ð°Ñ Ñ‡Ð°Ñтица. * **kTARGET** - чаÑтица мишени. Четвертый параметр, Ñто мода Ð´Ð»Ñ Ð²ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ / Ð²Ñ‹ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ñ€ÐµÐ»Ñтивизма. .. attention:: По умолчанию уÑтановлен релÑтивизм! Что бы иÑпользовать калаÑÑичÑекие формулы приведенные ниже, пользователь должет передать методу SetThetaRange четвертым параметром kFALSE. ПÑтый параметр - Ñреднее значение Ñнергий пучка в GeV. .. attention:: Ð’ релÑтивиÑÑ‚Ñком Ñлучае, нужно обÑзательно задать Ñреднюю Ñнергию пучка Ñ‚.к она иÑпользуетÑÑ Ð´Ð»Ñ Ñ€Ð°Ñчета диапозона розыгрыша! Ð”Ð»Ñ ÐЕ релÑтивиÑÑ‚Ñкого ÑÐ»ÑƒÑ‡Ð°Ñ ÑƒÐ³Ð»Ñ‹ переÑчитываютÑÑ Ð¿Ð¾ формулам, которые приведены ниже: |theta|\ :sub:`CM1` и |theta|\ :sub:`CM2` , где |theta|\ :sub:`CM1` и |theta|\ :sub:`CM2` крайние Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ñ€Ð°Ñчитываемого диапозона. Когда M\ :sub:`1` \< M\ :sub:`2` \ .. math:: 0 \leqslant \theta_1 \leqslant \pi\ ,\\ а когда M\ :sub:`1` \ > M\ :sub:`2` \ .. math:: 0 \leqslant \theta_1 \leqslant \theta_{1max} \leqslant \frac{\pi}{2}\ ,\\ в обоих ÑлучаÑÑ…: .. math:: \theta_{cm1} = \arccos\left [ -\frac{M_1}{M_2} + sin^2(\theta_1-d\theta) + cos(\theta_1-d\theta)\sqrt{1 - \frac{M_1^2}{M_2^2}sin^2(\theta_1-d\theta)} \right ]\ , \theta_{cm2} = \arccos\left [ -\frac{M_1}{M_2} + sin^2(\theta_1+d\theta) + cos(\theta_1+d\theta)\sqrt{1 - \frac{M_1^2}{M_2^2}sin^2(\theta_1+d\theta)} \right ]\ . Когда M\ :sub:`1` \ = M\ :sub:`2` \ .. math:: 0 \leqslant \theta_1 \leqslant \frac{\pi}{2}\ ,\\ .. math:: \theta_{cm1} = 2(\theta_1-d\theta) , \theta_{cm2} = 2(\theta_1+d\theta) . Ð”Ð»Ñ Ð¿ÐµÑ€Ð²Ð¾Ð½Ð°Ñ‡Ð°Ð»ÑŒÐ½Ð¾ покоившихÑÑ Ñ‡Ð°Ñтиц (во вÑех ÑлучаÑÑ…): .. math:: \theta_{cm1} = \pi - 2(\theta_2-d\theta) , \theta_{cm2} = \pi - 2(\theta_2+d\theta) . M\ :sub:`1` - маÑÑа налетающей чаÑтицы, M\ :sub:`2` - маÑÑа покоÑщейÑÑ Ñ‡Ð°Ñтицы, |theta|\ :sub:`1` - угол раÑÑеÑÐ½Ð¸Ñ Ð½Ð°Ð»ÐµÑ‚Ð°ÑŽÑ‰ÐµÐ¹ чаÑтицы (Лабе), |theta|\ :sub:`2` - угол вылета покоÑщейÑÑ Ñ‡Ð°Ñтицы (Лабе). d |theta| - полуширина выбираемого диапазона (Лабе). .. tip:: Задавать диапазон розыгрыша коÑвенно: через координату |theta|\ :sub:`Lab` \ центра диапазона розыгрыша и полуширину выбираемого диапазона d |theta| - предпочтительнее! Ðти параметры вÑегда извеÑтны пользователю, потому что вÑе Ñлементы геометрии позиционируетÑÑ Ð² Лабе! * Диапазон розыгрыша Ð´Ð»Ñ |phi| выбираетÑÑ Ñвно:: scattering->SetPhiRange(-20., 20.); Механизм работы клаÑÑа ~~~~~~~~~~~~~~~~~~~~~~ ДобавлÑем упругое раÑÑеÑние в коллекцию раÑпадов:: decayer->AddDecay(scattering); Ðиже опишем что будет проиÑходить поÑле Ñтого. КлаÑÑ ElasticScattering Ñодержит два оÑновных метода: Intit(), Stepping(). Bool_t ElasticScattering::Init() """""""""""""""""""""""""""""""" Данный метод вызываетÑÑ Ð² Ñамом начале ÑимулÑции, на Ñтапе инициализации. * ЗдеÑÑŒ проверÑетÑÑ:: if (!ERDecay::Init()) { return kFALSE; } fTargetIonPDG = TDatabasePDG::Instance()->GetParticle(fTargetIonName); if ( ! fTargetIonPDG ) { LOG(FATAL)<< "Target ion not found in pdg database!" << FairLogger::endl; return kFALSE; } * СчитаетÑÑ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½ розыгрыша углов |theta|\ :sub:`CM` \ - вызовом private процедуры:: ERElasticScattering::ThetaRangesLab2CM(DoubleÑ€_t pM, Double_t tM) где pM - маÑÑа налетающей чаÑтицы, а tM - чаÑтицы мишени. .. note:: Ð’ Ñлучае Ñвного Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ð° розыгрыша |theta|\ :sub:`CM` \ , метод опиÑанный выше не вызываетÑÑ! * Так же здеÑÑŒ формируетÑÑ ÐºÑƒÐ¼ÑƒÐ»ÑÑ‚Ð¸Ð²Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ - вызовом private метода:: ERElasticScattering::ThetaCDFRead(); Bool_t ElasticScattering::Steping() """"""""""""""""""""""""""""""""""" ВызываетÑÑ Ð½Ð° каждом шаге транÑпорта налетающего иона внутри объёма мишени. ЗдеÑÑŒ разыгрываютÑÑ ÑƒÐ³Ð»Ñ‹ вылета Ð´Ð»Ñ Ð¸Ð¾Ð½Ð¾Ð² - налетающего и мишени, Ñледующим образом:: // Generate random angles theta and phi Double_t theta = ThetaGen(); Double_t phi = fRnd->Uniform(fPhi1*DegToRad(), fPhi2*DegToRad()); Метод:: ERElasticScattering::ThetaGen(); генерирует угол |theta|\ :sub:`CM` из кумулÑтивной функции. Затем ионы Ñ Ð½Ð¾Ð²Ñ‹Ð¼Ð¸ характериÑтиками кидаютÑÑ Ð² Ñтек чаÑтиц Ð´Ð»Ñ Ð´Ð°Ð»ÑŒÐ½ÐµÐ¹ÑˆÐµÐ³Ð¾ транÑпорта. СвÑзь лабораторной и центра маÑÑ ÑиÑтем ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. figure:: _images/elastic_fig4.png :height: 600px :width: 600 px :align: center Ðа риÑунке выше ион Рупруго раÑÑеиваетÑÑ Ð½Ð° ионе B. Ð’ имплементации метода ElasticScattering::Steping() углы |theta|\ :sub:`CM` \ разыгрываютÑÑ Ð² ÑиÑтеме координат (на риÑ., выше выделена краÑным) у которой оÑÑŒ z направлена вдоль импульÑа первичного иона. Ðеобходимо повернуть ÑиÑтему координат (2) так что бы ее оÑÑŒ z Ñовпала Ñ-оÑью z из (3). С помощью методов TLorentzVector:: TLorentzVector::RotateZ(-phi); TLorentzVector::RotateY(theta); TLorentzVector::RotateZ(phi); Ð’ Ñтек чаÑтиц упруго раÑÑеÑвшаÑÑÑ Ð¸Ð¾Ð½Ñ‹ необходимо передать Ñ Ñ…Ð°Ñ€Ð°ÐºÑ‚ÐµÑ€Ð¸Ñтиками в лабораторной ÑиÑтеме координат: Px, Py, Pz и E - ÑнергиÑ. Ð”Ð»Ñ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð´Ð° из ÑиÑтемы центра маÑÑ Ð² лабораторную иÑпользуетÑÑ Boost:: TLorentzVector::Boost(TVector3 &); Подробнее об Ñтом можно прочеÑÑ‚ÑŒ здеÑÑŒ: https://root.cern/doc/v616/classTLorentzVector.html Полезные методы ~~~~~~~~~~~~~~~ * Метод возвращающий чиÑло взаимодейÑтвии в мишени по вÑем ÑобытиÑм в run-е:: scattering->GetInteractNumInTarget(); * Метод возвращающий Ñреднее арифметичеÑкое |theta|\ :sub:`CM` по вÑем ÑобытиÑм в run-е:: scattering->GetThetaCMMean(); * Метод возвращающий маÑÑу налетающего иона:: scattering->GetProjectileIonMass(); * Метод возвращающий маÑÑу иона мишени:: scattering->GetTargetIonMass(); * Метод возвращающий величину диапазона кумулÑтивной функции (CDFMax-CDFMin):: scattering->GetdThetaCDF(); Пример иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ ÐºÐ»Ð°ÑÑа ~~~~~~~~~~~~~~~~~~~~~~~~~~~ КлаÑÑ **ERElasticScattering** иÑпользовалÑÑ Ð´Ð»Ñ Ð¼Ð¾Ð´ÐµÐ»Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ ÑƒÐ¿Ñ€ÑƒÐ³Ð¾Ð³Ð¾ раÑÑеÑниÑ\ :sup:`15` \ N на \ :sup:`11` \ B. Ðиже предÑтавлен управлÑющий Ð¼Ð°ÐºÑ€Ð¾Ñ Ð´Ð»Ñ ÑимулÑции:: void sim(Int_t nEvents = 100, Int_t index = 0, TString outDir="output", Double_t angle = 20.) { gRandom->SetSeed(index); //---------------------Files----------------------------------------------- TString outFile; outFile.Form("%s/sim_%d.root", outDir.Data(), index); TString parFile; parFile.Form("%s/par_%d.root", outDir.Data(), index); // ------------------------------------------------------------------------ // ----- Timer -------------------------------------------------------- TStopwatch timer; timer.Start(); // ----- Create simulation run ---------------------------------------- ERRunSim* run = new ERRunSim(); /** Select transport engine * TGeant3 * TGeant4 **/ run->SetName("TGeant4"); // Transport engine run->SetOutputFile(outFile.Data()); // Output file // ------------------------------------------------------------------------ // ----- Runtime database --------------------------------------------- FairRuntimeDb* rtdb = run->GetRuntimeDb(); // ------------------------------------------------------------------------ // ----- Create media ------------------------------------------------- run->SetMaterials("N15.media.geo"); // Materials // ------------------------------------------------------------------------ //-------- Set MC event header -------------------------------------------- ERDecayMCEventHeader* header = new ERDecayMCEventHeader(); run->SetMCEventHeader(header); //------------------------------------------------------------------------- // ----- Create detectors ---------------------------------------------- FairModule* cave= new ERCave("CAVE"); cave->SetGeometryFileName("cave.geo"); run->AddModule(cave); FairModule* collimator = new ERCollimator(); // "N15B11_collimator", "N15B11_collimator" collimator->SetGeometryFileName("N15.collimator.root"); run->AddModule(collimator); ERDetector* target = new ERTarget("N15B11_target", kTRUE, 1); target->SetGeometryFileName("N15.target.root"); run->AddModule(target); FairDetector* detector = new ERN15B11Detector("N15B11detector", kTRUE, 1); detector->SetGeometryFileName("N15B11_detector.geo.root"); run->AddModule(detector); //------ ER Decayer ------------------------------------------------- //Ion 15N Int_t A = 15; Int_t Z = 7; Int_t Q = 3; ERDecayer* decayer = new ERDecayer(); ERElasticScattering* scattering = new ERElasticScattering("15Nto15N11B"); scattering->SetInputIon(Z,A,Q); scattering->SetTargetIon(5, 11, 5); // 11B scattering->SetThetaCDF("cos_tetta_cross.txt"); scattering->SetUniformPos(-0.00035,0.00035); scattering->SetStep(0.00001); //0.1 micron scattering->SetDecayVolume("cave"); //targetB11 scattering->SetDetectorsSlot(angle, 4.*0.262822833); scattering->SetPhiRange(-20., 20.); decayer->AddDecay(scattering); run->SetDecayer(decayer); // ----- Create PrimaryGenerator -------------------------------------- FairPrimaryGenerator* primGen = new FairPrimaryGenerator(); ERIonMixGenerator* generator = new ERIonMixGenerator("15N", Z, A, Q, 1); generator->SetKinERange(0.0427094, 0.0436017); // 0.0427094 : 0.0436017 Double32_t theta = 0.; Double32_t sigmaTheta = 5e-3*TMath::RadToDeg(); generator->SetThetaSigma(theta, sigmaTheta); // theta = 0., sigma = 5 mrad generator->SetPhiRange(0., 180.); // 0 : 180 Double32_t distanceToTarget = 50.; // work: 50 cm, test 0.5 micron: 0.00005+0.00035 generator->SetBoxXYZ(-0.5, -0.5, 0.5, 0.5, -distanceToTarget); // Xmin = -0.5, Ymin = -0.5, Xmax = 0.5, , Ymax = 0.5, Z primGen->AddGenerator(generator); run->SetGenerator(primGen); // ------------------------------------------------------------------------ //-------Set visualisation flag to true------------------------------------ run->SetStoreTraj(kFALSE); // or kTRUE //-------Set LOG verbosity ----------------------------------------------- FairLogger::GetLogger()->SetLogVerbosityLevel("LOW"); FairLogger::GetLogger()->SetLogScreenLevel("DEBUG"); //------- Initialize simulation run --------------------------------------- run->Init(); Int_t nSteps = -15000; //--- Runtime database ---------------------------------------------------- Bool_t kParameterMerged = kTRUE; /** @brief Returns curent theta in CM for Primary Ion. **/ FairParRootFileIo* parOut = new FairParRootFileIo(kParameterMerged); parOut->open(parFile.Data()); rtdb->setOutput(parOut); rtdb->saveOutput(); rtdb->print(); // ----- Run simulation ------------------------------------------------ run->Run(nEvents); // ----- Finish ------------------------------------------------------- timer.Stop(); Double_t rtime = timer.RealTime(); Double_t ctime = timer.CpuTime(); cout<< endl << endl; cout<< "Macro finished succesfully." << endl; cout<< "Output file is sim.root" << endl; cout<< "Parameter file is par.root" << endl; cout<< "Real time " << rtime << " s, CPU time " << ctime << "s" << endl << endl; } Результаты Ð¼Ð¾Ð´ÐµÐ»Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ ~~~~~~~~~~~~~~~~~~~~~~~~ .. figure:: _images/elastic_fig5.png :height: 600px :width: 600 px :align: center Ðа данном риÑунке мы отоброзили как некоторые физичеÑкие факторы влиÑÑŽÑ‚ на угловое разрешение. #. Мы начали Ñ Ð¸Ð´ÐµÐ°Ð»ÑŒÐ½Ð¾Ð¹ реакции Ñ Ð¸Ð´ÐµÐ°Ð»ÑŒÐ½Ñ‹Ð¼ пучком, без мишени, без коллиматора, но Ñ Ñ€ÐµÐ°Ð»Ð¸Ñтичной щелью детектора и поÑледовательно добавили Ñледующие реалиÑтичные ÑвойÑтва: #. 11B мишень толщиной 7 микрон #. ÐнергетичеÑкое размытие пучка иона 15N (42 : 43 ÐœÑÐ’) #. Размытие угла пучка иона 15N (sigma = 5 мрад) #. Размытие угла пучка иона 15N (0 : 2) #. X размытие пÑтна пучка на мишени (-0.5 : 0.5 Ñм) #. Y размытие пÑтна пучка на мишени (-0.5 : 0.5 Ñм) #. Коллиматор пучка (размер отверÑÑ‚Ð¸Ñ 1.5 Ñм) .. figure:: _images/elastic_fig6.png :height: 600px :width: 600 px :align: center Измеренное дифференциальное Ñечение как Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ ÑƒÐ³Ð»Ð° раÑÑеÑÐ½Ð¸Ñ Ð² ЦМ Ðа данном риÑунке предÑтавлено Ñравнение входного дифференциального ÑÐµÑ‡ÐµÐ½Ð¸Ñ Ð¸ выходного (полученного по результатам ÑимулÑции). ЗдеÑÑŒ можно видеть два главных Ñффекта: #. ÐŸÐ¾Ð»ÑƒÑ‡ÐµÐ½Ð½Ð°Ñ Ð·Ð°Ð²Ð¸ÑимоÑÑ‚ÑŒ ÑтановитьÑÑ Ð¼ÐµÐ½ÐµÐµ крутой в передних углах. #. Волновое поведение иÑходной кривой ÑтановитÑÑ Ð¼ÐµÐ½ÐµÐµ выраженным. Ð’ результате работы было продемонÑтрировано, что воÑÑтановленное дифференциальное Ñечение немного отличаетÑÑ Ð¾Ñ‚ входного ОÑновной причиной Ñтого Ñ€Ð°Ð·Ð»Ð¸Ñ‡Ð¸Ñ ÑвлÑетÑÑ Ñ€Ð°Ð·Ð¼ÐµÑ€ пÑтна пучка на мишени ВлиÑние длины щели оказалоÑÑŒ незначительно, Ñледовательно, она может быть увеличено Ð´Ð»Ñ Ð»ÑƒÑ‡ÑˆÐµÐ¹ ÑффективноÑти Ð¾Ð±Ð½Ð°Ñ€ÑƒÐ¶ÐµÐ½Ð¸Ñ Ð Ð°Ð·Ñ€Ð°Ð±Ð¾Ñ‚Ð°Ð½Ð½Ð¾Ðµ программное обеÑпечение будет иÑпользоватьÑÑ Ð´Ð»Ñ Ð¿Ð»Ð°Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸ анализа подобных ÑкÑпериментов в будущем. Interaction class ----------------- Ð ÐµÐ°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ñвоего взаимодейÑÑ‚Ð²Ð¸Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÑетÑÑ Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ ÐºÐ»Ð°ÑÑа, унаÑледованного от `ERDecay`. Коды раÑпадов раÑположены в дирeктории `decays`. Ð’ новом клаÑÑе необходимо напиÑать реализации методов: `Init`, `BeginEvent`, `FinishEvent`, `Stepping`. Ð’ методе `Init` необходимо проверить вÑе ли ионы и чаÑтицы, которые учавÑтвуют в раÑпаде добавлены в объект раÑпада и в Root библиотеку чаÑтиц - `TDatabasePDG`. :: if (fInputIon) { fInputIonPDG = TDatabasePDG::Instance()->GetParticle(fInputIonName); if ( ! fInputIonPDG ) { std::cerr << "ERTextDecay: Ion " << fInputIonName << " not found in database!"<< endl; return kFALSE; } } else{ std::cerr << "Input ion not defined"<< endl; return kFALSE; } Также необходимо проверить вÑе ли входные текÑтовые файлы и другие наÑтройки раÑпада указаны. :: if (fFileName == "") { cerr << "File for " << fName << " decay not defined!" << endl; return kFALSE; } Метод `BeginEvent` вызываетÑÑ Ð² начале каждого ÑобытиÑ. Стандартно в Ñтом методе необходимо реинициализировать чаÑÑ‚ÑŒ переменных раÑпада и разыграть вероÑтноÑтные характериÑтики раÑпада, в чаÑтноÑти, позицию раÑпада. :: fDecayFinish = kFALSE; if (fUniform){ fDecayPosZ = fRnd->Uniform(fUniformA, fUniformB); } if (fExponential){ fDecayPosZ = fExponentialStart + fRnd->Exp(fExponentialTau); } Метод `Stepping` вызываетÑÑ Ð½Ð° каждом шаге транÑпорта вÑех чаÑтиц. Ð’ нём закладываетÑÑ ÑƒÑловие раÑпада и добавлÑÑŽÑ‚ÑÑ Ð½Ð¾Ð²Ñ‹Ðµ треки в Ñтек треков. Ð¢Ð¸Ð¿Ð¸Ñ‡Ð½Ð°Ñ Ñтруктура Ñтого метода предÑтавлена далее. Проверка того, что мы раÑÑматриваем трекинг интереÑующего Ð½Ð°Ñ Ð¸Ð¾Ð½Ð° и уÑтановка малого шага трека Ð´Ð»Ñ Ñ‚Ð¾Ð³Ð¾ чтобы макÑимально точно выбрать позицию раÑпада: :: if(!fDecayFinish && gMC->TrackPid() == fInputIonPDG->PdgCode()){ gMC->SetMaxStep(0.01); gMC->TrackPosition(fDecayPos); Провека что раÑпад выполнитьÑÑ Ð¸Ð¼ÐµÐ½Ð½Ð¾ на Ñтом шаге: :: if (fDecayPos.Z() > fDecayPosZ){ gMC->TrackMomentum(fInputIonV); //Add new ion Int_t newTrackNb; vector<TLorentzVector> decay = fDecays[gMC->CurrentEvent()]; Добавление новых чаÑтиц в Ñтек Ð´Ð»Ñ Ñ‚Ñ€Ð½Ñпорта: :: gMC->GetStack()->PushTrack(1,gMC->GetStack()->GetCurrentTrackNumber(), fOutputIonPDG->PdgCode(), outputIonV.Px(),outputIonV.Py(),outputIonV.Pz(), outputIonV.E(), fDecayPos.X(), fDecayPos.Y(), fDecayPos.Z(), gMC->TrackTime(), 0., 0., 0., kPDecay, newTrackNb, fOutputIonPDG->Mass(), 0); Окончание раÑпада. ОÑтановка первичного иона. Возвращение макÑимального шага транÑпорта. Сохранение характериÑтик раÑпада в объект `MCEventHeader` . :: fDecayFinish = kTRUE; gMC->StopTrack(); gMC->SetMaxStep(10000.); SaveToEventHeader(); } } return kTRUE; Decay definition in macro ------------------------- Ð˜Ð½Ð¸Ñ†Ð¸Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð¼ÐµÐ½ÐµÐ´Ð¶ÐµÑ€Ð° запуÑка. :: void decay(Int_t nEvents = 10) { //---------------------Files----------------------------------------------- TString outFile= "sim.root"; TString parFile= "par.root"; // ------------------------------------------------------------------------ // ----- Timer -------------------------------------------------------- TStopwatch timer; timer.Start(); // ------------------------------------------------------------------------ // ----- Create simulation run ---------------------------------------- ERRunSim* run = new ERRunSim(); run->SetName("TGeant4"); run->SetOutputFile(outFile.Data()); // ------------------------------------------------------------------------ // ----- Runtime database --------------------------------------------- FairRuntimeDb* rtdb = run->GetRuntimeDb(); // ------------------------------------------------------------------------ // ----- Create media ------------------------------------------------- run->SetMaterials("media.geo"); // Materials // ------------------------------------------------------------------------ ЕÑли необходимо ÑохранÑÑ‚ÑŒ параметры раÑпада в выходной файл необходимо добавить `MCEventHeader`. :: //-------- Set MC event header -------------------------------------------- ERDecayMCEventHeader* header = new ERDecayMCEventHeader(); run->SetMCEventHeader(header); //------------------------------------------------------------------------- Добавить необходимую геометрию в Ñобытие: :: // ----- Create detectors ---------------------------------------------- FairModule* cave= new ERCave("CAVE"); cave->SetGeometryFileName("cave.geo"); run->AddModule(cave); FairModule* target = new ERTarget("Target", kTRUE, 1); target->SetGeometryFileName("Li10_target.geo.root"); run->AddModule(target); // ------------------------------------------------------------------------ Добавить ERDecayer и добавить в него Ñконфигурированные раÑпады: :: //------ ER Deacayer ------------------------------------------------- ERDecayer* decayer = new ERDecayer(); ERDecay* targetDecay = new ERDecayLi9DetoLi10_Li9n_p(); decayer->AddDecay(targetDecay); //------------------------------------------------------------------------- Добавить генератор первичного иона. :: // ----- Create PrimaryGenerator -------------------------------------- FairPrimaryGenerator* primGen = new FairPrimaryGenerator(); ERIonGenerator* ionGenerator = new ERIonGenerator("Li9",3,9,3,1); Double32_t kin_energy = 0.025*9; //GeV Double_t mass = ionGenerator->Ion()->GetMass(); Double32_t momentum = TMath::Sqrt(kin_energy*kin_energy + 2.*kin_energy*mass); //GeV ionGenerator->SetPRange(momentum, momentum); Double32_t theta1 = 0.; // polar angle distribution Double32_t theta2 = 0.0001*TMath::RadToDeg(); ionGenerator->SetThetaRange(theta1, theta2); ionGenerator->SetPhiRange(0, 360); ionGenerator->SetBoxXYZ(-0.4,-0.4,0.4,0.4,-10); primGen->AddGenerator(ionGenerator); run->SetGenerator(primGen); // ------------------------------------------------------------------------ Закончить инициализацию и запуÑтить раÑчёт: :: //------------------------------------------------------------------------- // ----- Runtime database --------------------------------------------- Bool_t kParameterMerged = kTRUE; FairParRootFileIo* parOut = new FairParRootFileIo(kParameterMerged); parOut->open(parFile.Data()); rtdb->setOutput(parOut); rtdb->saveOutput(); rtdb->print(); //------------------------------------------------------------------------- // ----- Run simulation ------------------------------------------------ run->Run(nEvents); //------------------------------------------------------------------------- // ----- Finish ------------------------------------------------------- timer.Stop(); Double_t rtime = timer.RealTime(); Double_t ctime = timer.CpuTime(); cout << endl << endl; cout << "Macro finished succesfully." << endl; cout << "Output file is sim.root" << endl; cout << "Parameter file is par.root" << endl; cout << "Real time " << rtime << " s, CPU time " << ctime << "s" << endl << endl; //------------------------------------------------------------------------- } ERTextDecay - decay from text file ---------------------------------- `ERTextDecay` - клаÑÑ Ñ€Ð°Ñпада, в котором чтение результатов раÑпада проиÑходит из текÑтового файла Ñледующей Ñтруктуры: :: 10000 8.00 1.00 1.00 0.0000 10.0000 0.1653 0.3100 90.0000 -45.0000 1.0000 0.8000 1.0000 0.7206406E+01 -0.1754454E+02 0.5639178E+02 -0.1327796E+03 0.7652269E+00 -0.3139226E+02 0.7600432E+02 0.1677931E+02 -0.2499952E+02 0.5677531E+02 0.2169820E+00 0.9067860E+01 -0.2866158E+02 -0.3239947E+02 -0.9974271E+02 -0.1909192E+02 -0.4091810E+01 0.1072426E+03 0.4775351E+02 0.3649128E+02 -0.7499936E+01 0.1777150E+00 0.7098366E+01 -0.4391382E+02 -0.1458367E+02 0.1816315E+02 0.9634398E+02 0.1606081E+02 -0.2588241E+02 -0.5243016E+02 -0.1477139E+01 0.7719253E+01 0.2744438E+00 ÐŸÐµÑ€Ð²Ð°Ñ Ñтрочка ÑвлÑетÑÑ ÑˆÐ°Ð¿ÐºÐ¾Ð¹ файла и параметрами генерации. Ð”Ð°Ð½Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð½Ðµ иÑпользуетÑÑ Ð¿Ñ€Ð¸ реализации раÑпада в ExpertRoot. Далее ÐºÐ°Ð¶Ð´Ð°Ñ Ñтрока в файле задает Ñобытие. Первое чиÑло - ÑÐ½ÐµÑ€Ð³Ð¸Ñ Ð²Ð¾Ð·Ð±ÑƒÐ¶Ð´ÐµÐ½Ð¸Ñ, также не иÑпользуетÑÑ Ð² добавлении раÑпада в транÑпорт. Далее запиÑаны вектора импульÑов выходов раÑпада. ПоÑледнÑÑ ÐºÐ¾Ð»Ð¾Ð½ÐºÐ° - угол реакции - тоже не иÑпользуетÑÑ. Ð’Ñе импульÑÑ‹ указываютÑÑ Ð² ÑиÑтеме центра маÑÑ Ñ€Ð°Ñпада. При чтении из файла импульÑÑ‹ переводÑÑ‚ÑÑ Ð² лабораторную СК Ñ ÑƒÑ‡Ñ‘Ñ‚Ð¾Ð¼ импульÑа первичного иона в момент раÑпада. Ð’Ñе файлы раÑпадов должны находитÑÑ Ð² папке `input`. Ð”Ð»Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ раÑпада в Ñобытие необходимо добавить в макроÑ: :: //------ ER Deacayer ------------------------- ERDecayer* decayer = new ERDecayer(); ERTextDecay* decay = new ERTextDecay("10Heto8He2n"); decay->SetInputIon(2,10,2); decay->SetOutputIon(2,8,2); decay->AddOutputParticle(2212); decay->AddOutputParticle(2212); decay->SetDecayPosZ(2.); decay->SetFileName("generator_10He_decay.dat"); decayer->AddDecay(decay); run->SetDecayer(decayer); При инициализации необходимо указать входной ион, выходной ион и набор выходных чаÑтиц через маÑÑовые чиÑла или pdg. Далее необходимо указать позицию раÑпада по Z и файл раÑпада Ñ Ð¸Ð¼Ð¿ÑƒÐ»ÑŒÑами выходных чаÑтиц. Позицию раÑпада также можно задать Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ равномерного раÑпределениÑ. Ðто умеÑтно Ð´Ð»Ñ Ñ‚Ð¾Ð½ÐºÐ¾Ð¹ мишени. :: SetUniformPos(Double_t a, Double_t b); И Ñ Ð¿Ð¾Ð¼Ð¾ÑˆÑŒÑŽ ÑкÑпоненциального раÑпределениÑ. Ðто умеÑтно Ð´Ð»Ñ Ñ‚Ð¾Ð»Ñтой мишени. :: SetExponentialPos(Double_t start, Double_t tau);