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