KaliVeda
Toolkit for HIC analysis
KVElasticScatterEvent.cpp
1 /*
2 $Id: KVElasticScatterEvent.cpp,v 1.5 2009/01/14 15:35:50 ebonnet Exp $
3 $Revision: 1.5 $
4 $Date: 2009/01/14 15:35:50 $
5 */
6 
7 //Created by KVClassFactory on Thu Dec 11 14:45:29 2008
8 //Author: eric bonnet,,,
9 
10 #include "KVElasticScatterEvent.h"
11 #include "KVPosition.h"
12 #include "KVDetector.h"
13 #include "KVTelescope.h"
14 #include "KVUnits.h"
15 #include "TRandom.h"
16 
17 using namespace std;
18 
20 
21 
22 
23 //_______________________________________________________________________
24 
25 
29 {
30  // Default constructor
31  init();
32 
33 }
34 
35 
36 
39 
41 {
42  // Destructor
43  delete proj;
44  delete targ;
45  if (kb2) delete kb2;
46 
47  if (sim_evt) delete sim_evt;
48  if (rec_evt) delete rec_evt;
49 
50  ClearHistos();
51  ClearTrees();
52 }
53 
54 
55 
62 
64 {
65  //Initialisation des variables
66  //par defaut
67  //theta 0,180 et phi 0,360
68  //tirage isotropique
69  //noyau de reference pour la direction de diffusion Projectile
70 
71  kIPPVector.SetXYZ(0, 0, 0);
72 
73  kchoix_layer = -1;
74  kXruth_evt = 0;
75  kTreatedNevts = 0;
76 
77  th_min = 1e-3;
78  th_max = 180;
79  phi_min = 0;
80  phi_max = 360;
81 
82  lhisto = 0;
83  ltree = 0;
84 
85  targ = new KVNucleus();
86  proj = new KVNucleus();
87 
88  rec_evt = 0;
89  sim_evt = 0;
90  ktarget = 0;
91  kb2 = 0;
92 
93  ResetBit(kProjIsSet);
94  ResetBit(kTargIsSet);
95  ResetBit(kHasTarget);
96  ResetBit(kIsUpdated);
97  ResetBit(kIsDetectionOn);
98 
99  SetDiffNucleus("PROJ");
100  SetRandomOption("isotropic");
101 
102  SetDetectionOn(kFALSE);
103  ChooseKinSol(1);
104 
105 }
106 
107 
108 
111 
113 {
114  //Set contents/entries to zero for predifined histograms, trees
115  kTreatedNevts = 0;
116  ResetHistos();
117  ResetTrees();
118 
119 }
120 
121 
122 
127 
129 {
130  //Define the entrance channel using KVDBSystem object
131  //Get projectile and target via KVDBSystem::GetKinematics()
132  //Get target material using KVDBSystem::GetTarget()
133  if (sys->GetKinematics()) {
134  SetProjNucleus(sys->GetKinematics()->GetNucleus(1));
135  SetTargNucleus(sys->GetKinematics()->GetNucleus(2));
136  SetTargetMaterial(sys->GetTarget());
137  }
138  else {
139  Error("SetSystem", "KVDBSystem pointer is not valid");
140  return;
141  }
142 }
143 
144 
145 
150 
152 {
153  //Define the entrance channel
154  //zp, ap, ekin, atomic number, mass number and kinetic energy (MeV) of the projectile
155  //zt, at, atomic number, mass number of the target
156  KVNucleus nn(zp, ap, ekin);
157  SetProjNucleus(&nn);
158  nn.SetZAandE(zt, at, 0.0);
159  SetTargNucleus(&nn);
160 
161 }
162 
163 
164 
167 
169 {
170  //Define new target nucleus
171  if (!nuc) return;
172  nuc->Copy(*targ);
173  targ->SetName("TARG");
174  SetBit(kTargIsSet);
175  ResetBit(kIsUpdated);
176 
177 }
178 
179 
180 
185 
187 {
188  //Defini le noyau auquel se réfère la direction de diffusion (theta, phi)
189  //name="PROJ" (default) diffusion du projectile
190  //name="TARG" diffusion de la cible
191 
192  if (name == "TARG") {
193  kDiffNuc = 4;
194  }
195  else {
196  kDiffNuc = 3;
197  if (name != "PROJ") {
198  Warning("SetDiffNucleus", "%s Le nom en argument doit etre PROJ ou TARG, par defaut on choisit le projectile", name.Data());
199  }
200  }
201 }
202 
203 
204 
209 
211 {
212  //Defini le mode de tirage aleatoire pour l'angle polaire
213  //opt="isotropic" ou "" (defaut) ou "random"
214  //voir KVPosition::GetRandomDirection()
215  kRandomOpt = opt;
216 
217 }
218 
219 
220 
223 
225 {
226 
227  //retoune kTRUE si l'option choisi est isotrope
228  return strcmp(kRandomOpt, "random");
229 
230 }
231 
232 
233 
241 
243 {
244  //Dans le cas d'une cinematique inverse (Zproj>Ztarget)
245  //deux solutions cinetiques sont possibles pour un meme angle de
246  //diffusion du projectile
247  //choix=1, on traite seulement la premiere solution ie diffusion a l arriere de la cible
248  //choix=2, on traite seulement la deuxieme solution ie diffusion a l avant de la cible
249  //choix=0, les deux solution sont traitees avec la meme probabilite
250  if (choix >= 0 && choix <= 2)
251  kChoixSol = choix;
252 
253 }
254 
255 
256 
259 
261 {
262  //Define new projectile nucleus
263  if (!nuc) return;
264  nuc->Copy(*proj);
265  proj->SetName("PROJ");
266  SetBit(kProjIsSet);
267  ResetBit(kIsUpdated);
268  proj->SetE0();
269 
270 }
271 
272 
273 
276 
278 {
279  //return the current projectile ("PROJ") or the target ("TARG") nucleus
280  KVString sname(name);
281  if (sname == "PROJ") return proj;
282  else if (sname == "TARG") return targ;
283  else return 0;
284 
285 }
286 
287 
288 
291 
293 {
294  //return the current projectile (ii=1) or the target (ii==2) nucleus
295  if (ii == 1) return proj;
296  else if (ii == 2) return targ;
297  else return 0;
298 
299 }
300 
301 
302 
306 
308 {
309  //Define a new target material where the nuclei will be propagated
310  // if IsRandomized=kTRUE, the interaction point are randomly determined
311  if (!targ) return;
312  if (ktarget) delete ktarget;
313 
314  ktarget = new KVTarget(*targ);
315  ktarget->SetRandomized(IsRandomized);
316  SetBit(kHasTarget);
317  ResetBit(kIsUpdated);
318 }
319 
320 
321 
323 
325 {
326 
327  if (gMultiDetArray) {
328  gMultiDetArray->SetSimMode(On);
330  SetBit(kIsDetectionOn, On);
331  ResetBit(kIsUpdated);
332 
333  }
334  else {
335  if (On)
336  Warning("MakeDetection", "Detection asked but no multiDetArray defined");
337  }
338 
339 }
340 
341 
342 
345 
347 {
348  //return the current target material
349  return ktarget;
350 
351 }
352 
353 
354 
369 
371 {
372  //Protected Method called by ValidateEntrance() method
373  //Genere the KV2Body object which manage the 2 body kinematics
374  //for the elastik scatter
375  //
376  //Store the original momentum of the projectile nuclei
377  //
378  //
379  //Define the KVEvent and KVReconstructedEvent pointer
380  //where are stored the projectile/target nuclei couple after diffusion / detection
381  //StartEvents() methods
382  //
383  //Make a copy of projectile and target nuclei for the KVEvent
384  //
385 
386  Info("GenereKV2Body", "On genere le KV2Body");
387  if (kb2) delete kb2;
388  kb2 = new KV2Body(*proj, *targ);
389  kb2->CalculateKinematics();
390 
391  //GetNucleus("PROJ")->SetE0();
392 
393  //Creer ou clear les deux pointeurs associes aux evts simules et reconstruits
394  StartEvents();
395 
396  GetNucleus("PROJ")->Copy(*sim_evt->AddParticle());
397  GetNucleus("TARG")->Copy(*sim_evt->AddParticle());
398 }
399 
400 
401 
405 
407 {
408  //Define the KVEvent and KVReconstructedEvent pointer
409  //where are stored the projectile/target nuclei couple after diffusion / detection
410  if (!sim_evt) sim_evt = new KVSimEvent();
411  else sim_evt->Clear();
412 
413  if (!rec_evt) rec_evt = new KVReconstructedEvent();
414  else rec_evt->Clear();
415 
416 }
417 
418 
419 
424 
426 {
427 
428  //Define the nucleus target from the type
429  //of the given layer which belongs to the predefined target
430  //layer_name has to be the chemical symbol of the material
431 
432  if (!IsTargMatSet())
433  return kFALSE;
434 
435  if (GetTarget()->GetLayers()->GetEntries() == 0) return kFALSE;
436  KVMaterial* mat = 0;
437  if (layer_name == "") {
438  kchoix_layer = 1;
439  mat = GetTarget()->GetLayerByIndex(kchoix_layer);
440  }
441  else {
442  if (!(mat = GetTarget()->GetLayer(layer_name))) {
443  printf("le nom du layer %s ne correspond a aucun present dans le cible\n", layer_name.Data());
444  printf("Attention le layer doit etre appele par son symbol (ie Calcium -> Ca)");
445  ktarget->GetLayers()->Print();
446  return kFALSE;
447  }
448  kchoix_layer = GetTarget()->GetLayerIndex(layer_name);
449  }
450 
451  KVNucleus* nuc = new KVNucleus();
452  nuc->SetZandA(TMath::Nint(mat->GetZ()), TMath::Nint(mat->GetMass()));
453 
454  SetTargNucleus(nuc);
455 
456  return kTRUE;
457 
458 }
459 
460 
461 
487 
489 {
490  //Check if there is :
491  // - one define projectile nuclei : SetProjNucleus()
492  // - one define target nuclei : SetTargNucleus()
493  // - one define material target : SetTargetMaterial() [Optionnel]
494  //Si pas de noyau cible défini mais une cible est definie le noyau cible est definie a partir de celle-ci
495  //Si la cible comporte plusieurs layers, le premier est choisi pour definir le noyau cible
496  // see DefineTargetNucleusFromLayer() method
497  //
498  //
499  //Check if the gMultiDetArray is valid, put it in SimMode in order to able the detection and reconstruction
500  //If GetTarget() return kTRUE, put it in the gMultiDetArray
501  //If not, check if there is already one in the gMultiDetArray
502  //If there is one, use it for the following
503  //If there is no target material at all make diffusion without
504  //
505  //Generate the KV2Body object to calculate kinematics of the elastic scatter
506  //
507  //if histograms and trees is defined do nothing for this objects
508  //if not DefineTrees() and DefineHistos() are called.
509  //if you want to regenerate histograms and/or trees
510  //call ClearHistos() and/or ClearTrees() before using ValidateEntrance()
511  //
512  //Return kTRUE if everything is ready
513  //
514 
515  if (!IsProjNucSet()) {
516  Error("ValidateEntrance", "Il n'y a pas de noyau projectile -> use SetProjNucleus()");
517  return kFALSE;
518  }
519 
520  if (!IsTargNucSet()) {
521  Info("ValidateEntrance", "Il n'y a pas de noyau cible");
522  if (!IsTargMatSet()) {
523  Error("ValidateEntrance", "Il n'y a pas de noyau cible -> use SetTargNucleus() ou SetTargetMaterial");
524  return kFALSE;
525  }
526  else {
527  if (DefineTargetNucleusFromLayer())
528  Info("ValidateEntrance", "Definition du noyau cible via DefineTargetNucleusFromLayer()");
529  }
530  }
531 
532  if (IsDetectionOn()) {
533  if (GetTarget()) {
534  if (gMultiDetArray->GetTarget() && gMultiDetArray->GetTarget() == ktarget) {
535 
536  }
537  else {
538  //Fait un clone
539  gMultiDetArray->SetTarget(GetTarget());
540  delete ktarget;
541  ktarget = gMultiDetArray->GetTarget();
542  }
543  }
544  else if (gMultiDetArray->GetTarget()) {
545  ktarget = gMultiDetArray->GetTarget();
546  }
547  else {
548  Warning("ValidateEntrance", "Pas de calcul de perte dans la cible ... ");
549  }
550  //DefineAngularRange(gMultiDetArray);
551  }
552  else {
553  Info("ValidateEntrance", "The elastic scatter events will not be detected/filtered");
554  }
555 
556  GenereKV2Body();
557  Info("ValidateEntrance", "Fin de GenereKV2Body");
558  //Define histograms/trees only at the first call
559  //of validate entrance
560 
561  if (!ltree) DefineTrees();
562 
563  ClearHistos();
564  DefineHistos();
565 
566  SetBit(kIsUpdated);
567 
568  return kTRUE;
569 
570 }
571 
572 
573 
574 
578 
580 {
581  //process ntimes elastic scatter
582  //if reset=kTRUE, reset histograms, trees and counter before
583  Info("Process", "Je Suis dans Process ... Youpee");
584 
585  if (!IsUpdated())
586  if (!ValidateEntrance()) return;
587 
588  if (reset) Reset();
589  Int_t nn = 0;
590  while (nn < ntimes) {
591  MakeDiffusion();
592  nn += 1;
593  if ((nn % 1000) == 0) {
594  Info("Process", "%d/%d diffusions treated", nn, ntimes);
595  }
596  }
597  Info("Process", "End of process : %d diffusions performed", kTreatedNevts);
598 }
599 
600 
601 
613 
615 {
616  //
617  //Propagation dans la cible du projectile jusqu'au point d interaction
618  // PropagateInTargetLayer();
619  //Tirage aleatoire d'un couple theta phi pour la direction de diffusion du projectile
620  //Determination de la cinematique de la voie de sortie
621  // SetAnglesForDiffusion(the,phi);
622  //Filtre si un multidetecteur est defini
623  // Filter
624  //Traitement de l evt (remplissage d'arbre ou d'histo
625  // TreateEvent();
626 
627  sim_evt->GetParameters()->Clear();
628  for (auto& knuc : SimEventIterator(sim_evt)) {
629  knuc.GetParameters()->Clear();
630  knuc.RemoveAllGroups();
631  }
632 
633  //-------------------------
634  if (IsTargMatSet()) {
635  NewInteractionPointInTargetLayer();
636  PropagateInTargetLayer();
637  }
638  //-------------------------
639 
640 
641  Double_t tmin = GetTheta("min");
642  if (tmin >= kb2->GetMaxAngleLab(kDiffNuc)) {
643  GetNucleus("PROJ")->SetMomentum(*GetNucleus("PROJ")->GetPInitial());
644  return;
645  }
646  Double_t tmax = GetTheta("max");
647 
648  if (tmax <= kb2->GetMinAngleLab(kDiffNuc)) {
649  GetNucleus("PROJ")->SetMomentum(*GetNucleus("PROJ")->GetPInitial());
650  return;
651  }
652 
653  if (tmin < kb2->GetMinAngleLab(kDiffNuc)) tmin = kb2->GetMinAngleLab(kDiffNuc);
654  if (tmax > kb2->GetMaxAngleLab(kDiffNuc)) tmax = kb2->GetMaxAngleLab(kDiffNuc);
655 
656  Double_t pmin = GetPhi("min");
657  Double_t pmax = GetPhi("max");
658 
659  kposalea.SetPolarMinMax(tmin, tmax);
660  kposalea.SetAzimuthalMinMax(pmin, pmax);
661 
662  Double_t th_deg, ph_deg;
663  kposalea.GetRandomAngles(th_deg, ph_deg, kRandomOpt);
664 
665  SetAnglesForDiffusion(th_deg, ph_deg);
666 
667  ((TH2F*)lhisto->FindObject("phi_theta"))->Fill(th_deg, ph_deg);
668  ((TH1F*)lhisto->FindObject("costheta"))->Fill(TMath::Cos(TMath::DegToRad()*th_deg));
669 
670 
671  if (IsDetectionOn()) {
672  Filter();
673  }
674  else {
675  if (IsTargMatSet())
676  SortieDeCible();
677  }
678 
679  TreateEvent();
680 
681  kTreatedNevts += 1;
682 }
683 
684 
685 
690 
692 {
693  //Choose a new interaction point in the current target layer
694  //This position can be read via the GetInteractionPointInTargetLayer()
695  //method
696  if (kchoix_layer != -1) {
697  TVector3 dir = GetNucleus("PROJ")->GetMomentum();
698  ktarget->SetInteractionLayer(kchoix_layer, dir);
699  //kIPPVector = ktarget->GetInteractionPoint();
700  }
701  kIPPVector = ktarget->GetInteractionPoint(GetNucleus("PROJ"));
702  ((TH1F*)lhisto->FindObject("target_layer_depth"))->Fill(kIPPVector.Z());
703 }
704 
705 
706 
715 
717 {
718  //Apply Energy loss calculation to the entering projectile
719  //along its path in the target layer to the interation point
720  //
721  //if a gMultiDetArray is defined the outgoing (after diffusion) pathes are not treated here but
722  //in the Filter() method
723  //
724  //if not is treated in the SortieDeCible method
725 
726  Double_t eLostInTarget = GetNucleus("PROJ")->GetKE();
727  ktarget->SetIncoming(kTRUE);
728  ktarget->DetectParticle(GetNucleus("PROJ"), 0);
729  eLostInTarget -= GetNucleus("PROJ")->GetKE();
730 
731  //Energie perdue jusqu'au point d interaction
732  sim_evt->GetParticleWithName("PROJ")->GetParameters()->SetValue("TARGET In", eLostInTarget);
733  //On modifie l'energie du projectile dans KV2Body
734  //pour prendre en compte l energie deposee dans la cible
735  //avant de faire le calcul de la cinematique
736  if (GetNucleus("PROJ")->GetKE() == 0) {
737  GetNucleus("PROJ")->Print();
738  printf("%lf / %lf\n", eLostInTarget, proj->GetKE());
739  }
740  kb2->GetNucleus(1)->SetKE(GetNucleus("PROJ")->GetKE());
741  kb2->CalculateKinematics();
742 
743  ktarget->SetIncoming(kFALSE);
744 
745 }
746 
747 
748 
751 
753 {
754  //return the last interaction point in the target
755  return kIPPVector;
756 
757 }
758 
759 
760 
761 
766 
768 {
769  //Apply Energy loss calculation in target material for the outgoing projectile
770  //and target
771  //
772 
773  ktarget->SetOutgoing(kTRUE);
774  for (auto& knuc : SimEventIterator(sim_evt)) {
775  knuc.SetE0();
776  Double_t eLostInTarget = knuc.GetKE();
777  ktarget->DetectParticle(&knuc, 0);
778  eLostInTarget -= knuc.GetKE();
779  knuc.GetParameters()->SetValue("TARGET Out", eLostInTarget);
780  knuc.SetMomentum(*knuc.GetPInitial());
781  }
782 
783  ktarget->SetOutgoing(kFALSE);
784 
785 }
786 
787 
788 
789 
798 
800 {
801  //Determination a partir du theta choisi
802  //de l'energie cinetique du projectile diffuse
803  //All kinematics properties calculated in the KV2Body class
804  //are accessible via the KV2Body& GetKinematics() method
805  //
806  // WARNING: in inverse kinematics, there are two projectile energies
807  // for each lab angle.
808  Double_t ediff;
809  Double_t ediff1, ediff2;
810  Int_t nsol_kin;
811 
812  nsol_kin = kb2->GetELab(kDiffNuc, theta, kDiffNuc, ediff1, ediff2);
813 
814  if (nsol_kin == 1) {
815  ediff = ediff1;
816  }
817  else {
818  if (kChoixSol == 1) ediff = ediff1;
819  else if (kChoixSol == 2) {
820  ediff = ediff2;
821  }
822  else {
823  Int_t choix = TMath::Nint(gRandom->Uniform(0.5, 2.5));
824  if (choix == 2) ediff = ediff2;
825  else ediff = ediff1;
826  }
827  }
828  Bool_t sol2 = (ediff == ediff2);
829 
830  kXruth_evt = kb2->GetXSecRuthLab(theta, kDiffNuc);
831 
832  //On modifie l energie et les angles du projectile ou cible diffusé(e)
833  //puis par conservation, on deduit ceux du noyau complementaire
834  KVNucleus* knuc = 0;
835 
836  if (kDiffNuc == 3)
837  knuc = sim_evt->GetParticleWithName("PROJ");
838  else
839  knuc = sim_evt->GetParticleWithName("TARG");
840 
841  knuc->SetKE(ediff);
842  knuc->SetTheta(theta);
843  knuc->SetPhi(phi);
844  ((TH2F*)lhisto->FindObject("ek_theta"))->Fill(knuc->GetTheta(), knuc->GetKE());
845 
846  //Conservation de l impulsion
847  //Conservation de l energie tot
848  TVector3 ptot = proj->Vect() + targ->Vect();
849  Double_t etot = proj->E() + targ->E();
850  //on retire la contribution du noyau diffusé
851  ptot -= knuc->Vect();
852  etot -= knuc->E();
853  //on met a jour les pptés la cible ou projectile diffusé(e)
854 
855  if (kDiffNuc == 3)
856  knuc = sim_evt->GetParticleWithName("TARG");
857  else
858  knuc = sim_evt->GetParticleWithName("PROJ");
859 
860  TLorentzVector q(ptot, etot);
861  knuc->Set4Mom(q);
862 
863  ((TH2F*)lhisto->FindObject("ek_theta"))->Fill(knuc->GetTheta(), knuc->GetKE());
864 
865  sim_evt->SetNumber(kTreatedNevts);
866 
867  sim_evt->GetParameters()->SetValue("XRuth", kXruth_evt);
868  sim_evt->GetParameters()->SetValue("ThDiff", theta);
869  sim_evt->GetParameters()->SetValue("EkDiff", ediff1);
870  sim_evt->GetParameters()->SetValue("IPz", kIPPVector.Z());
871 
872  if (sol2)
873  sim_evt->GetParameters()->SetValue("Sol2", 1);
874 
875  //L' energie cinetique du projectile est reinitialisee
876  //pour la prochaine diffusion
877  GetNucleus("PROJ")->SetMomentum(*GetNucleus("PROJ")->GetPInitial());
878 
879 }
880 
881 
882 
887 
889 {
890  //Simulate passage of the projectile/target couple
891  //through the multidetector refered by the gMultiDetArray pointer
892  //if it is not valid do nothing
893 
894  Fatal("Filter", "Must be reimplemented using KVDetectionSimulator and/or KVEventFiltering");
895  // gMultiDetArray->DetectEvent(sim_evt, rec_evt);
896 
897 
898 }
899 
900 
901 
921 
923 {
924  //Rempli l'arbre ElasticScatter
925  //Boucle sur tous les parametres associés a l evt (KVEvent::GetParameters() et au projectiles et cible
926  //qui le constituent GetParticle(1)->GetParameters()
927  // Chaque parametre devient un alias de l'arbre ElasticScatter
928  // pour une utilisation a posteriori plus facile.
929  // - pour les parametres de l'evt, on donne directement le nom du parametre
930  // - pour les particule :
931  // N1_[nom_du parametre] pour les projectiles et N2_[nom_du parametre] pour les cibles diffusés
932  //
933  // Exemple avec l'utilisation de TTree::Draw
934  // Si on veut voir le spectre en energie laissé par les projectiles diffuses dans la "CI_0601"
935  // au lieu de faire
936  // GetTree("Simulated_evts")->Draw("Simulated_evts->GetParticle(1)->GetParameters()->GetValue(\"CI_0601\")")
937  // on fera
938  // GetTree("Simulated_evts")->Draw("N1_CI_0601")
939  //
940  // Generation des correlation Energie Cinetique (Ek) vs Angle de diffusion (theta)
941  // pour tous les cas de détection
942 
943  if (rec_evt->GetMult() > 0) {
944  TTree* tt = (TTree*)ltree->FindObject("ElasticScatter");
945  tt->Fill();
946  }
947  /*
948  TString snom,stit;
949  KVNamedParameter* nm = 0;
950 
951  TIter it(sim_evt->GetParameters()->GetList());
952  while ( (nm = (KVNamedParameter* )it.Next()) ){
953  snom.Form("%s",nm->GetName());
954  if (snom.Contains(" ")) snom.ReplaceAll(" ","_");
955  stit.Form("Simulated_evts->GetParameters()->GetDoubleValue(\"%s\")",nm->GetName());
956  tt->SetAlias(snom.Data(),stit.Data());
957  }
958  TIter it1(sim_evt->GetParticle(1)->GetParameters()->GetList());
959  while ( (nm = (KVNamedParameter* )it1.Next()) ){
960  snom.Form("N1_%s",nm->GetName());
961  if (snom.Contains(" ")) snom.ReplaceAll(" ","_");
962  stit.Form("Simulated_evts->GetParticle(1)->GetParameters()->GetDoubleValue(\"%s\")",nm->GetName());
963  tt->SetAlias(snom.Data(),stit.Data());
964  }
965  TIter it2(sim_evt->GetParticle(2)->GetParameters()->GetList());
966  while ( (nm = (KVNamedParameter* )it2.Next()) ){
967  snom.Form("N2_%s",nm->GetName());
968  if (snom.Contains(" ")) snom.ReplaceAll(" ","_");
969  stit.Form("Simulated_evts->GetParticle(2)->GetParameters()->GetDoubleValue(\"%s\")",nm->GetName());
970  tt->SetAlias(snom.Data(),stit.Data());
971  }
972 
973  if (IsDetectionOn()){
974  TH2F* hh = 0;
975  KVNucleus* knuc = 0;
976  while ( (knuc = sim_evt->GetNextParticle()) ){
977 
978  if ( knuc->GetParameters()->HasParameter("DETECTED") ){
979  if ( !strcmp(knuc->GetParameters()->GetStringValue("DETECTED"),"") ){
980  snom.Form("ek_theta_DETECTED");
981  if ( !(hh = (TH2F* )lhisto->FindObject(snom.Data())) ){
982  Double_t totalE = GetNucleus(1)->GetKE();
983  lhisto->Add(new TH2F(snom.Data(),"DETECTED",180,0,180,TMath::Nint(totalE*11),0,totalE*1.1));
984  hh = (TH2F* )lhisto->Last(); hh->SetXTitle("#theta_{ lab}"); hh->SetYTitle("Ek_{ lab}");
985  }
986  }
987  else {
988  snom.Form("ek_theta_%s",knuc->GetParameters()->GetStringValue("DETECTED"));
989  if ( !(hh = (TH2F* )lhisto->FindObject(snom.Data())) ){
990  Double_t totalE = GetNucleus(1)->GetKE();
991  lhisto->Add(new TH2F(snom.Data(),knuc->GetParameters()->GetStringValue("DETECTED"),180,0,180,TMath::Nint(totalE*11),0,totalE*1.1));
992  hh = (TH2F* )lhisto->Last(); hh->SetXTitle("#theta_{ lab}"); hh->SetYTitle("Ek_{ lab}");
993  }
994  }
995  }
996  else if ( knuc->GetParameters()->HasParameter("UNDETECTED") ){
997  if ( !strcmp(knuc->GetParameters()->GetStringValue("UNDETECTED"),"") ){
998  snom.Form("ek_theta_UNDETECTED");
999  if ( !(hh = (TH2F* )lhisto->FindObject(snom.Data())) ){
1000  Double_t totalE = GetNucleus(1)->GetKE();
1001  lhisto->Add(new TH2F(snom.Data(),"UNDETECTED",180,0,180,TMath::Nint(totalE*11),0,totalE*1.1));
1002  hh = (TH2F* )lhisto->Last(); hh->SetXTitle("#theta_{ lab}"); hh->SetYTitle("Ek_{ lab}");
1003  }
1004  }
1005  else {
1006  snom.Form("ek_theta_%s",knuc->GetParameters()->GetStringValue("UNDETECTED"));
1007  if ( !(hh = (TH2F* )lhisto->FindObject(snom.Data())) ){
1008  Double_t totalE = GetNucleus(1)->GetKE();
1009  lhisto->Add(new TH2F(snom.Data(),knuc->GetParameters()->GetStringValue("UNDETECTED"),180,0,180,TMath::Nint(totalE*11),0,totalE*1.1));
1010  hh = (TH2F* )lhisto->Last(); hh->SetXTitle("#theta_{ lab}"); hh->SetYTitle("Ek_{ lab}");
1011  }
1012  }
1013  }
1014  else {
1015  knuc->Print();
1016  }
1017  if (hh)
1018  hh->Fill(knuc->GetTheta(),knuc->GetKE());
1019  }
1020  }
1021  */
1022 
1023 }
1024 
1025 
1026 
1028 
1030 {
1031 
1032  kb2->Print();
1033 
1034  printf("#####################\n");
1035  printf("## KVElasticScatterEvent::Print() ##\n");
1036  printf("# Diffusion elastique traitee :\n");
1037  printf("# %s+%s@%1.2lf MeV/A\n",
1038  GetNucleus(1)->GetSymbol(),
1039  GetNucleus(2)->GetSymbol(),
1040  GetNucleus(1)->GetKE() / GetNucleus(1)->GetA()
1041  );
1042  if (IsTargMatSet()) {
1043  printf("-------------------------\n");
1044  printf("# Propagation dans une cible de:\n");
1045  for (Int_t nn = 0; nn < GetTarget()->GetLayers()->GetEntries(); nn += 1) {
1046  Double_t epaiss = GetTarget()->GetLayerByIndex(nn + 1)->GetAreaDensity() / (KVUnits::mg / pow(KVUnits::cm, 2));
1047  printf("#\ttype:%s epaisseur:%lf (mg/cm**2) / %lf\n",
1048  GetTarget()->GetLayerByIndex(nn + 1)->GetType(),
1049  epaiss,
1050  GetTarget()->GetLayerByIndex(nn + 1)->GetThickness()
1051  );
1052  }
1053  }
1054  printf("-------------------------\n");
1055  if (IsDetectionOn()) {
1056  printf("# Detection par %s\n", gMultiDetArray->GetName());
1057  }
1058  printf("#####################\n");
1059 
1060 }
1061 
1062 
1069 
1071 {
1072  //Definition of control histograms
1073  //- phi_theta : filled with angles choosen to determine the direction of the diffused projectile
1074  //- target_layer_depth : interaction point position in the target
1075  //- ek_theta : filled with energies and polar angles of projectile and target nuclei after diffusion
1076  //they are detected by the multidetarray
1077  Info("DefineHistos", "DefineHistos");
1078  lhisto = new KVHashList();
1079  lhisto->SetOwner(kTRUE);
1080  TH2F* h2 = 0;
1081  TH1F* h1 = 0;
1082 
1083  lhisto->Add(new TH2F("phi_theta", "phi_theta", 180, 0, 180, 360, 0, 360));
1084  h2 = (TH2F*)lhisto->Last();
1085  h2->SetXTitle("#theta_{ lab}");
1086  h2->SetYTitle("#phi_{ lab}");
1087  lhisto->Add(new TH1F("costheta", "costheta", 200, -1, 1));
1088  h1 = (TH1F*)lhisto->Last();
1089  h1->SetXTitle("cos #theta_{ lab}");
1090  if (IsTargMatSet()) {
1091  Info("DefineHistos", "Creation de l histo interaction dans la cible");
1092  Float_t thickness = GetTarget()->GetThickness();
1093  lhisto->Add(new TH1F("target_layer_depth", "target_layer_depth", TMath::Nint(thickness * 110), 0, thickness * 1.1));
1094  h1 = (TH1F*)lhisto->Last();
1095  h1->SetXTitle("IP position (mg / cm**2)");
1096  }
1097  Float_t totalE = GetNucleus(1)->GetKE();
1098  lhisto->Add(new TH2F("ek_theta", "ek_theta", 180, 0, 180, TMath::Nint(totalE * 11), 0, totalE * 1.1));
1099  h2 = (TH2F*)lhisto->Last();
1100  h2->SetXTitle("#theta_{ lab}");
1101  h2->SetYTitle("Ek_{ lab}");
1102 
1103 }
1104 
1105 
1106 
1109 
1111 {
1112  //return the list where histo are stored
1113  return lhisto;
1114 
1115 }
1116 
1117 
1120 
1122 {
1123 
1124  //Reset histo in the list
1125  lhisto->Execute("Reset", "");
1126 
1127 }
1128 
1129 
1132 
1134 {
1135  //Efface la liste des histo et leur contenu et met le pointeur a zero
1136  if (lhisto) delete lhisto;
1137  lhisto = 0;
1138 
1139 }
1140 
1141 
1142 
1153 
1155 {
1156  //Definition of trees
1157  //
1158  //Par defaut un seul arbre : ElasticScatter where simulated events are stored
1159  //sous forme de KVEvent
1160  //Lors du remplissage de l arbre ( methode TreateEvent)
1161  //les parametres associes au KVEvent::GetParameters et au KVNucleus::GetParameters (projectile et cible)
1162  //sont scannés et leur nom et le moyen d'y accéder ajouté aux alias de l arbre pour une utilisation
1163  //plus aisé de celui_ci
1164  //
1165 
1166  Info("DefineTrees", "DefineTrees");
1167  ltree = new KVHashList();
1168  ltree->SetOwner(kTRUE);
1169  TTree* tt = 0;
1170 
1171  tt = new TTree("ElasticScatter", IsA()->GetName());
1172  KVEvent::MakeEventBranch(tt, "Simulated_evts", sim_evt);
1173  ltree->Add(tt);
1174 }
1175 
1176 
1177 
1180 
1182 {
1183  //return the list where histo are stored
1184  return ltree;
1185 
1186 }
1187 
1188 
1189 
1192 
1194 {
1195  //Efface la liste des arbres et leur contenu et met le pointeur a zero
1196  if (ltree) delete ltree;
1197  ltree = 0;
1198 
1199 }
1200 
1201 
1202 
1206 
1208 {
1209  //Reset the tree contents
1210  //and aliases for the "ElasticScatter" tree
1211  ltree->Execute("Reset", "");
1212  if (((TTree*)ltree->FindObject("ElasticScatter"))->GetListOfAliases())
1213  ((TTree*)ltree->FindObject("ElasticScatter"))->GetListOfAliases()->Clear();
1214 
1215 }
1216 
1217 
1218 
1224 
1226 {
1227  //Define in which angular (polar and azimuthal) range
1228  //The projectile diffusion direction will be randomized
1229  //If this method is not used
1230  //Default range is \theta [0,180] and \phi [0,360]
1231  if (tmin != -1) th_min = tmin;
1232  if (tmax != -1) th_max = tmax;
1233  if (pmin != -1) phi_min = pmin;
1234  if (pmax != -1) phi_max = pmax;
1235 
1236 }
1237 
1238 
1239 
1248 
1250 {
1251  //Define in which angular (polar and azimuthal) range
1252  //The projectile diffusion direction will be randomized
1253  //From the geometry of the given object obj
1254  //This method is defined for object derived from
1255  // - KVPosition (ie KVTelescope KVRing KVGroup etc ...)
1256  // - KVDetector (in this case, the KVTelescope it belongs to is used)
1257  // - KVMultiDetArray
1258 
1259  Double_t tmin = -1, tmax = -1, pmin = -1, pmax = -1;
1260  if (obj->InheritsFrom("KVPosition")) {
1261  KVPosition* pos_obj = (KVPosition*)obj;
1262  tmin = pos_obj->GetThetaMin();
1263  tmax = pos_obj->GetThetaMax();
1264  pmin = pos_obj->GetPhiMin();
1265  pmax = pos_obj->GetPhiMax();
1266  }
1267  else if (obj->InheritsFrom("KVDetector")) {
1268  KVTelescope* pos_obj = (KVTelescope*)((KVDetector*)obj)->GetParentStructure("TELESCOPE");
1269  tmin = pos_obj->GetThetaMin();
1270  tmax = pos_obj->GetThetaMax();
1271  pmin = pos_obj->GetPhiMin();
1272  pmax = pos_obj->GetPhiMax();
1273  }
1274  else if (obj->InheritsFrom("KVASMultiDetArray")) {
1275  Warning("DefineAngularRange(KVASMultiDetArray*)", "Needs reimplementing");
1276  /*KVASMultiDetArray* pos_obj=(KVASMultiDetArray* )obj;
1277  KVSeqCollection* ll = pos_obj->GetGroups();
1278  KVASGroup* gr=0;
1279  Double_t tmin2=180,tmax2=0;
1280  Double_t pmin2=360,pmax2=0;
1281  for (Int_t nl=0;nl<ll->GetEntries();nl+=1){
1282  gr = (KVASGroup* )ll->At(nl);
1283  if (gr->GetThetaMin()<tmin2) tmin2 = gr->GetThetaMin();
1284  if (gr->GetThetaMax()>tmax2) tmax2 = gr->GetThetaMax();
1285  if (gr->GetPhiMin()<pmin2) pmin2 = gr->GetPhiMin();
1286  if (gr->GetPhiMax()>pmax2) pmax2 = gr->GetPhiMax();
1287  }
1288  tmin = tmin2;
1289  tmax = tmax2;
1290  pmin = pmin2;
1291  pmax = pmax2;*/
1292  }
1293  else {
1294  printf("les objects de type %s ne sont pas implemente dans KVElasticScatterEvent::DefineAngularRange\n", obj->IsA()->GetName());
1295  return;
1296  }
1297 
1298  DefineAngularRange(tmin, tmax, pmin, pmax);
1299 
1300 }
1301 
1302 
1303 
1307 
1309 {
1310  //Return the limite in theta range (polar angle)
1311  //opt has to be "min" or "max"
1312  if (opt == "min") return th_min;
1313  else if (opt == "max") return th_max;
1314  else return -1;
1315 
1316 }
1317 
1318 
1319 
1323 
1325 {
1326 
1327  //Return the limite in phi range (azimuthal angle)
1328  //opt has to be "min" or "max"
1329  if (opt == "min") return phi_min;
1330  else if (opt == "max") return phi_max;
1331  else return -1;
1332 
1333 }
1334 
1335 
int Int_t
#define e(i)
bool Bool_t
char Char_t
float Float_t
constexpr Bool_t kFALSE
double Double_t
constexpr Bool_t kTRUE
const char Option_t
char name[80]
float * q
R__EXTERN TRandom * gRandom
TClass * IsA() const override
Relativistic binary kinematics calculator.
Definition: KV2Body.h:166
KVNucleus * GetNucleus(Int_t i) const
Definition: KV2Body.cpp:456
Database class used to store information on different colliding systems studied during an experiment....
Definition: KVDBSystem.h:52
KVTarget * GetTarget() const
Definition: KVDBSystem.h:80
KV2Body * GetKinematics()
Definition: KVDBSystem.cpp:80
simulate ElasticScatterEvent and answer of a given (multi-)detector : A + B -> A + B
virtual void SetProjNucleus(KVNucleus *nuc)
Define new projectile nucleus.
virtual void SetSystem(KVDBSystem *sys)
virtual TVector3 & GetInteractionPointInTargetLayer()
return the last interaction point in the target
void Print(Option_t *="") const
virtual void ClearTrees()
Efface la liste des arbres et leur contenu et met le pointeur a zero.
virtual void DefineAngularRange(TObject *)
void SetDiffNucleus(KVString name="PROJ")
virtual void SetTargNucleus(KVNucleus *nuc)
Define new target nucleus.
Bool_t IsIsotropic() const
retoune kTRUE si l'option choisi est isotrope
virtual void SetAnglesForDiffusion(Double_t theta, Double_t phi)
void SetRandomOption(Option_t *opt="isotropic")
KVHashList * GetTrees() const
return the list where histo are stored
KVTarget * GetTarget() const
return the current target material
virtual void Process(Int_t ntimes=1, Bool_t reset=kTRUE)
virtual void ClearHistos()
Efface la liste des histo et leur contenu et met le pointeur a zero.
virtual void ResetHistos()
Reset histo in the list.
virtual void SetTargetMaterial(KVTarget *targ, Bool_t IsRandomized=kTRUE)
void SetDetectionOn(Bool_t On=kTRUE)
KVHashList * GetHistos() const
return the list where histo are stored
virtual ~KVElasticScatterEvent()
Destructor.
virtual void Reset()
Set contents/entries to zero for predifined histograms, trees.
KVNucleus * GetNucleus(const Char_t *name) const
return the current projectile ("PROJ") or the target ("TARG") nucleus
void ChooseKinSol(Int_t choix=1)
Bool_t DefineTargetNucleusFromLayer(KVString layer_name="")
Double_t GetPhi(KVString opt) const
Double_t GetTheta(KVString opt) const
static void MakeEventBranch(TTree *tree, const TString &branchname, T &event, Int_t bufsize=10000000)
Definition: KVEvent.h:210
Extended version of ROOT THashList.
Definition: KVHashList.h:29
Description of physical materials used to construct detectors & targets; interface to range tables.
Definition: KVMaterial.h:89
Double_t GetZ() const
Definition: KVMaterial.cpp:390
Double_t GetMass() const
Definition: KVMaterial.cpp:302
KVTarget * GetTarget()
void SetFilterType(Int_t t)
virtual void SetSimMode(Bool_t on=kTRUE)
virtual void SetTarget(KVTarget *target)
Description of properties and kinematics of atomic nuclei.
Definition: KVNucleus.h:123
void Copy(TObject &) const override
Copy this KVNucleus into the KVNucleus object referenced by "obj".
Definition: KVNucleus.cpp:827
void SetZandA(Int_t z, Int_t a)
Set atomic number and mass number.
Definition: KVNucleus.cpp:713
void SetZAandE(Int_t z, Int_t a, Double_t ekin)
Set atomic number, mass number, and kinetic energy in MeV.
Definition: KVNucleus.cpp:725
void SetTheta(Double_t theta)
Definition: KVParticle.h:696
void SetPhi(Double_t phi)
Definition: KVParticle.h:700
Double_t GetTheta() const
Definition: KVParticle.h:683
void SetKE(Double_t ecin)
Definition: KVParticle.cpp:246
void Set4Mom(const TLorentzVector &p)
Definition: KVParticle.h:592
Double_t GetKE() const
Definition: KVParticle.h:617
Base class used for handling geometry in a multidetector array.
Definition: KVPosition.h:91
Double_t GetPhiMax() const
Definition: KVPosition.h:146
Double_t GetPhiMin() const
Definition: KVPosition.h:142
Double_t GetThetaMin() const
Definition: KVPosition.h:150
Double_t GetThetaMax() const
Definition: KVPosition.h:154
Event containing KVReconstructedNucleus nuclei reconstructed from hits in detectors.
Container class for simulated nuclei, KVSimNucleus.
Definition: KVSimEvent.h:22
Extension of ROOT TString class which allows backwards compatibility with ROOT v3....
Definition: KVString.h:73
Calculation/correction of energy losses of particles through an experimental target.
Definition: KVTarget.h:128
Wrapper class for iterating over nuclei in KVSimEvent accessed through base pointer or reference.
virtual Bool_t Add(const TH1 *h, const TH1 *h2, Double_t c1=1, Double_t c2=1)
virtual void SetXTitle(const char *title)
virtual void SetYTitle(const char *title)
TVector3 Vect() const
Double_t E() const
const char * GetName() const override
virtual Bool_t InheritsFrom(const char *classname) const
virtual TClass * IsA() const
virtual Double_t Uniform(Double_t x1, Double_t x2)
const char * Data() const
RVec< PromoteTypes< T0, T1 > > pow(const T0 &x, const RVec< T1 > &v)
RVec< T > Filter(const RVec< T > &v, F &&f)
TH1F * h1
const long double mg
Definition: KVUnits.h:74
const long double cm
Definition: KVUnits.h:66
void Error(const char *location, const char *fmt,...)
void Info(const char *location, const char *fmt,...)
void Fatal(const char *location, const char *fmt,...)
void Warning(const char *location, const char *fmt,...)
void init()
Type GetType(const std::string &Name)
Int_t Nint(T x)
constexpr Double_t DegToRad()
Double_t Cos(Double_t)
auto * tt
ClassImp(TPyArg)