4 #include "KVIDZAFromZGrid.h"
6 #include "KVIDZALine.h"
10 #include "KVMultiGaussIsotopeFit.h"
30 fIgnoreMassID =
false;
55 i.fPIDRange = fPIDRange;
56 i.fPIDRangeZList = fPIDRangeZList;
57 fTables.
Copy(i.fTables);
59 i.fIgnoreMassID = fIgnoreMassID;
82 fIgnoreMassID =
false;
84 check_pidranges_and_massfits();
103 fPIDRangeZList.
Clear();
120 double pidmin, pidmax, pid;
122 else if (
type == 2) {
127 itv->
add(aa, pid, pidmin, pidmax);
131 fPIDRangeZList.
Add(zz);
146 fPIDRangeZList.
Clear();
179 fPIDRangeZList.
Add(ivs->
GetZ());
202 auto z_int = itvs->
GetZ();
203 fPIDRangeZList.
Remove(z_int);
233 fPIDRangeZList.
Clear();
235 for (
int ii = 1; ii < 50; ii++) {
251 int KVIDZAFromZGrid::is_inside(
double pid)
const
268 if (it && it->
is_inside(pid))
return zint + 1;
273 if (it && it->
is_inside(pid))
return zint - 1;
310 for (
auto z : zlist) {
314 fitparams.
Set(massfit);
328 void KVIDZAFromZGrid::check_pidranges_and_massfits()
335 if(fPar.HasParameter(
"MASSFITS"))
341 auto massfits_copy = massfits;
342 massfits.Inter(pidrange);
343 if(massfits != massfits_copy)
345 KVError::Error(
this,
"KVIDZAFromZGrid::check_pidranges_and_massfits",
346 "Grid %s has inconsistent MASSFITS (%s) and PIDRANGE (%s) - correcting...",
347 GetName(), massfits_copy.AsString(), pidrange.AsString());
350 for(
auto z : massfits)
355 "Grid %s : removing fit for Z=%d...",
364 for (
auto z : massfits) {
365 if(pidrange.Contains(z))
370 fitparams.
Set(massfit);
375 if(nuc.IsResonance())
377 "Grid %s includes resonance %s",
GetName(), nuc.GetSymbol() );
378 else if(!nuc.IsKnown())
380 "Grid %s includes unknown isotope %s",
GetName(), nuc.GetSymbol() );
381 else if(!nuc.IsStable() && !nuc.GetLifeTime())
383 "Grid %s includes unstable isotope %s",
GetName(), nuc.GetSymbol() );
390 auto pipi = pidr.
Next();
392 pidalist.
Add(pipi.Next().Atoi());
394 auto alist_orig = alist;
395 alist.Inter(pidalist);
396 if(alist != alist_orig)
399 "Grid %s has inconsistent masses for Z=%d for MASSFIT (%s) and PIDRANGE (%s)",
414 auto A = fitfunc->
GetA(idr->
PID, P);
459 auto fLinearHisto =
new TH1F(
"fLinearHisto",
"fLinearHisto", zbins, zmin, zmax);
464 auto available_cpu = WITH_MULTICORE_CPU;
467 std::vector<std::thread> jobs;
476 std::cout <<
"Will run " << available_cpu <<
" threads, each for " << xbins_per_cpu <<
" bins in X" << std::endl;
478 int nthreads = available_cpu;
480 std::cout <<
"Histo linearization using " << nthreads <<
" threads..." << std::endl;
482 for (
int job = 0; job < available_cpu; ++job) {
483 auto imin = 1 + job * xbins_per_cpu;
484 auto imax = (job + 1) * xbins_per_cpu;
485 if (job == available_cpu - 1) imax = fHisto->
GetNbinsX();
489 grid_copy->Initialize();
490 grid_copies.
Add(grid_copy);
493 jobs.push_back(std::thread([ =, &nthreads]() {
497 bool no_mass_id_zone_defined = (grid_copy->GetInfos()->
FindObject(
"MassID") ==
nullptr);
499 for (
int i = imin; i <= imax; ++i) {
500 for (
int j = 1; j <= fHisto->
GetNbinsY(); j++) {
502 if (poids == 0)
continue;
509 if (x0 < 4)
continue;
513 Double_t weight = (kmax == 20 ? poids / 20. : 1.);
514 for (
int k = 0; k < kmax; k++) {
517 if (grid_copy->IsIdentifiable(
x,
y)) {
519 grid_copy->KVIDZAGrid::Identify(
x,
y, &idr);
520 if (no_mass_id_zone_defined || idr.
HasFlag(grid_copy->GetName(),
"MassID")) {
522 fLinearHisto->Fill(PID, weight);
529 std::cout <<
"...remaining threads: " << nthreads << std::endl;
532 for (
auto& j : jobs) {
533 if (j.joinable()) j.join();
573 if (!idr->
IDOK)
return;
575 bool have_pid_range_for_Z = fPIDRange && fPIDRangeZList.
Contains(idr->
Z);
577 bool have_mass_fit_for_Z = (mass_fit_for_Z !=
nullptr);
578 bool mass_id_success =
false;
580 if ((have_mass_fit_for_Z || have_pid_range_for_Z)
583 if (have_mass_fit_for_Z)
587 if (mass_id_success) {
612 if (mass_id_success) idr->
SetComment(
"slight ambiguity of A, which could be larger");
613 else idr->
SetComment(
"slight ambiguity of Z, which could be larger");
616 if (mass_id_success) idr->
SetComment(
"slight ambiguity of A, which could be smaller");
617 else idr->
SetComment(
"slight ambiguity of Z, which could be smaller");
620 if (mass_id_success) idr->
SetComment(
"slight ambiguity of A, which could be larger or smaller");
621 else idr->
SetComment(
"slight ambiguity of Z, which could be larger or smaller");
624 if (mass_id_success) idr->
SetComment(
"point is outside of mass identification range");
625 else idr->
SetComment(
"Z identification correct but no mass identification");
628 if (mass_id_success) idr->
SetComment(
"point is in between two isotopes A & A+2 (e.g. 5He, 8Be, 9B)");
629 else idr->
SetComment(
"point is in between two lines of different Z, too far from either to be considered well-identified");
632 idr->
SetComment(
"(x,y) is below first line in grid");
635 idr->
SetComment(
"(x,y) is above last line in grid");
638 idr->
SetComment(
"no identification: (x,y) out of range covered by grid");
658 int zint = is_inside(idr->
PID);
659 if (!zint)
return -1;
660 if (zint != idr->
Z) idr->
Z = zint;
664 if (it) res = it->
eval(idr);
680 if (!itvs->
GetNPID())
continue;
681 fPIDRangeZList.
Add(itvs->
GetZ());
688 if (!itvs->
GetNPID())
continue;
696 KVError::Error(
this,
"ExportToGrid",
"Grid %s has interval set for Z=%d including resonance %s",
706 auto massfits_copy = massfits;
707 massfits.
Inter(fPIDRangeZList);
708 if(massfits != massfits_copy)
710 ::Info(
"KVIDZAFromZGrid::ExportToGrid()",
711 "Grid %s : will correct MASSFITS(%s) to be same as PIDRANGE(%s)",
714 massfits = fPIDRangeZList;
717 for(
auto z : massfits)
721 ::Info(
"KVIDZAFromZGrid::ExportToGrid()",
722 "Grid %s : removing fit for Z=%d for which no PIDRANGE exists (%s)",
738 double pid = idr->
PID;
739 if (pid < 0.5)
return 0.;
749 interval* left_int(
nullptr), *right_int(
nullptr);
754 ares = inter->
GetA();
777 if (!right_int || !left_int) {
785 int dA = right_int->
GetA() - left_int->GetA();
875 std::map<double,int> toto;
879 auto it = std::begin(toto);
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
R__EXTERN TRandom * gRandom
char * Form(const char *fmt,...)
virtual void WriteToAsciiFile(std::ofstream &gridfile)
static void SetAutoAdd(Bool_t yes=kTRUE)
static Bool_t GetAutoAdd()
const Char_t * GetName() const override
const KVNameValueList * GetParameters() const
const KVList * GetIdentifiers() const
Hybrid charge & mass identification grid.
const KVList * GetIntervalSets() const
bool MassIdentificationFromMultiGaussFit(KVMultiGaussIsotopeFit *, KVIdentificationResult *) const
void Initialize() override
KVMultiGaussIsotopeFit * GetMultiGaussFit(int z) const
interval_set * GetIntervalSet(int zint) const
void WriteToAsciiFile(std::ofstream &gridfile) override
void Identify(Double_t x, Double_t y, KVIdentificationResult *) const override
virtual double DeduceAfromPID(KVIdentificationResult *idr) const
void AddIntervalSet(interval_set *)
add an interval set to the grid, updating the corresponding parameters
TH1 * LinearizeHistoToPID(const TH2 *hdata, int nbins=100) const override
void SetOnlyZId(Bool_t=kTRUE) override
void RemoveIntervalSet(int zint)
Remove interval set for given Z from grid.
void ReadFromAsciiFile(std::ifstream &gridfile) override
void Copy(TObject &obj) const override
void ReadFromAsciiFile(std::ifstream &gridfile) override
void Copy(TObject &) const override
Copy this to 'obj'.
void Initialize() override
void Identify(Double_t x, Double_t y, KVIdentificationResult *) const override
Base class for graphical cuts used in particle identification.
virtual Double_t GetPID() const
Full result of one attempted particle identification.
Bool_t IDOK
general quality of identification, =kTRUE if acceptable identification made
void SetComment(const Char_t *c)
Bool_t Aident
= kTRUE if A of particle established
Double_t PID
= "real" Z if Zident==kTRUE and Aident==kFALSE, "real" A if Zident==Aident==kTRUE
Int_t A
A of particle found (if Aident==kTRUE)
Int_t Z
Z of particle found (if Zident==kTRUE)
Int_t IDquality
specific quality code returned by identification procedure
void Clear(Option_t *opt="") override
Reset to initial values.
Bool_t HasFlag(std::string grid_name, TString flag)
Bool_t Zident
=kTRUE if Z of particle established
Extended TList class which owns its objects by default.
Function for fitting PID mass spectra.
std::optional< int > GetA(double PID, double &P) const
double GetInterpolatedA(double PID) const
Handles lists of named parameters with different types, a list of KVNamedParameter objects.
void SetValue(const Char_t *name, value_type value)
void RemoveParameter(const Char_t *name)
const Char_t * GetStringValue(const Char_t *name) const
bool Set(const KVString &)
TString GetTStringValue(const Char_t *name) const
Description of properties and kinematics of atomic nuclei.
const Char_t * GetSymbol(Option_t *opt="") const
Bool_t IsResonance(std::optional< int > z={}, std::optional< int > a={}) const
Strings used to represent a set of ranges of values.
void Inter(const KVNumberList &list)
Bool_t Contains(Int_t val) const
returns kTRUE if the value 'val' is contained in the ranges defined by the number list
void Clear(Option_t *="") override
Empty number list, reset it to initial state.
const Char_t * AsString(Int_t maxchars=0) const
void Remove(Int_t)
Remove value 'n' from the list.
void Add(Int_t)
Add value 'n' to the list.
void Copy(TObject &obj) const override
TObject * First() const override
TObject * Remove(TObject *obj) override
Remove object from list.
void Add(TObject *obj) override
TObject * FindObject(const char *name) const override
void AddLast(TObject *obj) override
Int_t GetSize() const override
void Clear(Option_t *option="") override
TObject * At(Int_t idx) const override
Extension of ROOT TString class which allows backwards compatibility with ROOT v3....
void Begin(TString delim) const
KVString Next(Bool_t strip_whitespace=kFALSE) const
void Add(TObject *obj) override
virtual void SetPoint(Int_t i, Double_t x, Double_t y)
virtual Double_t Eval(Double_t x, TSpline *spline=nullptr, Option_t *option="") const
TObject * FindObject(const char *name) const override
virtual Int_t GetNbinsY() const
virtual Int_t GetNbinsX() const
virtual Double_t GetBinContent(Int_t bin) const
virtual void SetName(const char *name)
virtual void Info(const char *method, const char *msgfmt,...) const
virtual Double_t Uniform(Double_t x1, Double_t x2)
const char * Data() const
Bool_t IsWhitespace() const
TString & Remove(EStripType s, char c)
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
TString & ReplaceAll(const char *s1, const char *s2)
TString GetListOfMasses()
bool is_inside(double pid)
bool is_above(double pid)
void add(int aa, double pid, double pidmin=-1., double pidmax=-1.)
double eval(KVIdentificationResult *idr)
interval_set(int zz, int type)
bool is_right_of(double pid)
bool is_left_of(double pid)
bool is_inside(double pid)
void Error(UserClass p, const char *location, const char *va_(fmt),...)
void Warning(UserClass p, const char *location, const char *va_(fmt),...)
Double_t Min(Double_t a, Double_t b)