NCFS-Pack
A generic (astro)particle physics analysis framework
Loading...
Searching...
No Matches
NcAstrolab.cxx
Go to the documentation of this file.
1
31
33
187
188#include "NcAstrolab.h"
189#include "Riostream.h"
190
191ClassImp(NcAstrolab); // Class implementation to enable ROOT I/O
192
194NcAstrolab::NcAstrolab(const char* name,const char* title) : TTask(name,title),NcTimestamp()
195{
201
202 fExperiment="User";
203 fLabId=0;
204 fToffset=0;
205 fRefs=0;
206 fSigs=0;
207 fNen[0]=0;
208 fNen[1]=0;
209 fBias=0;
210 fGal=0;
211 fIndices=0;
212 fUsMeridian=0;
213 fMeridian=0;
214 fProj="none";
215 fCanvas=0;
216 fHist[0]=0;
217 fHist[1]=0;
218 fMarkers=0;
219 fMarkerSize[0]=1.5;
220 fMarkerSize[1]=1;
221 fMarkerSize[2]=1.5;
222 fMarkerSize[3]=0.3;
223 fMarkerStyle[0]=29;
224 fMarkerStyle[1]=8;
225 fMarkerStyle[2]=34;
226 fMarkerStyle[3]=8;
227 fMarkerColor[0]=kRed;
228 fMarkerColor[1]=kBlue;
229 fMarkerColor[2]=kBlack;
230 fMarkerColor[3]=kBlack;
231 fSkyMapPanel=0;
232 fTscmode=0;
233 fTscmin=0;
234 fTscmax=0;
235 fTscfunc=0;
236 fRscmode=0;
237 fDscmin=0;
238 fDscmax=0;
239 fDscfunc=0;
240 fThetascmin=0;
241 fThetascmax=0;
242 fThetascfunc=0;
243 fPhiscmin=0;
244 fPhiscmax=0;
245 fPhiscfunc=0;
246 fRan=0;
247 fMaxDt=-1;
248 fSolUpdate=0;
249
250 // Standard values (Particle Data Group 2018) for some (astro)physical parameters
251 fSpeedC=299792458;
252 fQe=1.602176565e-19;
253 fMe=0.510998928;
254 fMmu=105.6583715;
255 fMtau=1776.82;
256 fAmu=931.494061;
257 fMp=1.007276466812*fAmu;
258 fMn=1.00866491600*fAmu;
259 fMW=80.385;
260 fGammaW=2.085;
261 fMZ=91.1876;
262 fGammaZ=2.4952;
263 fAlphaEM=1./137.035999074;
264 fFermi=1.1663787e-5;
265 fPlanck=6.62606957e-34;
266 fBoltz=1.3806488e-23;
267 fNewton=6.67384e-11;
268 fGn=9.80665;
269 fAu=1.49597870700e11;
270 fPc=3.08567758149e16;
271 // Cosmological parameters from the final Planck 2018 results (arXiv:1807.06209)
272 fHubble=67.4;
273 fOmegaM=0.315;
274 fOmegaR=5.38e-5;
275 fOmegaL=0.685;
276 fOmegaB=0.0492;
277 fOmegaC=0.264;
278
279 // Some derived (astro)physical parameters c.q. conversion constants
280 fHbar=6.58211928e-22;
281 fHbarc=197.3269718;
282 fHbarc2=3.89379338e-4;
283
284 // Function to parametrize the Neutrino-Lepton kinematic opening angle
285 fNuAngle=0;
286
287 // Specifications of the data from a ROOT input Tree
288 fDataDir=0;
289 fDataFrame="undefined";
290 fDataMode="undefined";
291
292 // Identifiers of the signal and background energy profiles
293 fSigEmode="-";
294 fBkgEmode="-";
295
296 // Storage for transient burst investigations
298
299 // Initialize the default values for the burst parameters
300 SetBurstParameter("*",0);
301
302 // Load the UTC parameters
304
305 // Set the default local frame convention
306 // X-axis pointing South (=Greenwich)
307 // Y-axis pointing East
308 // Z-axis pointing towards Zenith
309 SetLocalFrame(90,0,90,90,0,0);
310
311 // First initialization of the various SkyMapPanel GUI parameters.
312 // In case SkyMapPanel() is invoked, the current Lab settings will be imported.
313 fSkyMapPanel=0;
314 fMapTS.LoadUTCparameterFiles();
315 for (Int_t i=0; i<3; i++)
316 {
317 fMapLabLBI[i]=0;
318 }
319 fMapLabU=0;
320 fMapLabE=0;
321 fMapLabLocL=0;
322 fMapLabLocB=0;
323 fMapLabLocU="deg";
324 fMapLabExpName="User";
325 fMapLabId=0;
328 fMapDate="";
329 fMapTime="";
330 fMapTimeType="-";
331 fMapDateTime="";
332 fMapLabTS=kTRUE;
333 for (Int_t i=0; i<6; i++)
334 {
335 fMapLabLframe[i]=0;
336 }
337 fMapCinfo="Lab";
338 fMapTinfo=-1;
339 fMapUinfo="deg";
340 fMapIname="";
341 fMapEa=0;
342 fMapEua="deg";
343 fMapEb=0;
344 fMapEub="deg";
345 fMapEtype=1;
346 fMapEcoord="-";
347 fMapEmode="-";
348 fMapEname="";
349 fMapDcoord="-";
350 fMapProj="-";
351 fMapDmode="-";
352 for (Int_t i=0; i<5; i++)
353 {
354 fMapDoptions[i]=kFALSE;
355 }
356 fMapNmax=-1;
357 fMapNdigs=1;
358 fMapDname="";
359 for (Int_t i=0; i<10; i++)
360 {
361 fMapSolar[i]=kFALSE;
362 }
363 fMapMerMode=0;
364 fMapMerC=0;
365 fMapMerUc="deg";
366 fMapMarkSize=1;
367 fMapMarkStyle=23;
368 fMapMarkColor=kRed;
369 fMapMarkType=0;
370}
371
373{
379
380 if (fRefs)
381 {
382 delete fRefs;
383 fRefs=0;
384 }
385 if (fSigs)
386 {
387 delete fSigs;
388 fSigs=0;
389 }
390 if (fIndices)
391 {
392 delete fIndices;
393 fIndices=0;
394 }
395 for (Int_t i=0; i<2; i++)
396 {
397 if (fHist[i])
398 {
399 delete fHist[i];
400 fHist[i]=0;
401 }
402 }
403 if (fMarkers)
404 {
405 delete fMarkers;
406 fMarkers=0;
407 }
408 if (fCanvas)
409 {
410 if (gROOT->GetListOfCanvases()->FindObject("NcAstrolab")) delete fCanvas;
411 fCanvas=0;
412 }
413 if (fTscfunc)
414 {
415 delete fTscfunc;
416 fTscfunc=0;
417 }
418 if (fDscfunc)
419 {
420 delete fDscfunc;
421 fDscfunc=0;
422 }
423 if (fThetascfunc)
424 {
425 delete fThetascfunc;
426 fThetascfunc=0;
427 }
428 if (fPhiscfunc)
429 {
430 delete fPhiscfunc;
431 fPhiscfunc=0;
432 }
433 if (fRan)
434 {
435 delete fRan;
436 fRan=0;
437 }
438
439 if (fNuAngle)
440 {
441 delete fNuAngle;
442 fNuAngle=0;
443 }
444
446 {
447 delete fBurstParameters;
449 }
450
451 // Remove the subtasks from the internal TTask list without deleting them
452 if (fTasks) fTasks->Clear();
453}
454
456{
462
465 fLabId=t.fLabId;
466 fL=t.fL;
467 Int_t size=0;
468 fRefs=0;
469 if (t.fRefs)
470 {
471 size=t.fRefs->GetSize();
472 fRefs=new TObjArray(size);
473 for (Int_t i=0; i<size; i++)
474 {
475 NcSignal* sx=(NcSignal*)t.fRefs->At(i);
476 if (sx) fRefs->AddAt(sx->Clone(),i);
477 }
478 }
479 fSigs=0;
480 if (t.fSigs)
481 {
482 size=t.fSigs->GetSize();
483 fSigs=new TObjArray(size);
484 for (Int_t i=0; i<size; i++)
485 {
486 NcSignal* sx=(NcSignal*)t.fSigs->At(i);
487 if (sx) fSigs->AddAt(sx->Clone(),i);
488 }
489 }
490 fNen[0]=t.fNen[0];
491 fNen[1]=t.fNen[1];
492 fBias=0;
493 fGal=0;
494 fIndices=0;
495 fMeridian=-999;
496 fProj="none";
497 fCanvas=0;
498 for (Int_t ih=0; ih<2; ih++)
499 {
500 fHist[ih]=0;
501 }
502 fMarkers=0;
503 for (Int_t i=0; i<4; i++)
504 {
505 fMarkerSize[i]=t.fMarkerSize[i];
506 fMarkerStyle[i]=t.fMarkerStyle[i];
507 fMarkerColor[i]=t.fMarkerColor[i];
508 }
509
510 fTscmode=0;
511 fTscmin=0;
512 fTscmax=0;
513 fTscfunc=0;
514 SetTimeScramble(t.fTscmode,t.fTscmin,t.fTscmax,t.fTscfunc);
515
516 fRscmode=0;
517 fDscmin=0;
518 fDscmax=0;
519 fDscfunc=0;
520 fThetascmin=0;
521 fThetascmax=0;
522 fThetascfunc=0;
523 fPhiscmin=0;
524 fPhiscmax=0;
525 fPhiscfunc=0;
526 SetPositionScramble(t.fRscmode,t.fDscmin,t.fDscmax,t.fDscfunc,t.fThetascmin,t.fThetascmax,t.fThetascfunc,t.fPhiscmin,t.fPhiscmax,t.fPhiscfunc);
527
528 fRan=0;
529 NcRandom* ran=t.fRan;
530 if (ran) fRan=new NcRandom(*ran);
531
532 fMaxDt=t.fMaxDt;
533
534 TF1* fx=t.fNuAngle;
535 if (fx) fNuAngle=(TF1*)fx->Clone();
536
537 NcDevice* dx=t.fBurstParameters;
538 if (dx) fBurstParameters=(NcDevice*)dx->Clone();
539}
540
541void NcAstrolab::Data(Int_t mode,TString u,Bool_t utc)
542{
564
565 TString name=GetName();
566 TString title=GetTitle();
567 printf(" *%-s::Data*",ClassName());
568 if (name!="") printf(" Name : %-s",name.Data());
569 if (title!="") printf(" Title : %-s",title.Data());
570 printf("\n");
571
572 Double_t l,b;
573 GetLabPosition(l,b,"deg");
574 printf(" Position longitude : "); PrintAngle(l,"deg",u,3);
575 printf(" latitude : "); PrintAngle(b,"deg",u,3);
576 printf(" for detector ID : %-i \n",fLabId);
577 printf(" Local user reference frame orientation w.r.t X0=South, Y0=East and Z0=Zenith : \n");
578 printf(" (Note : At the Poles (e.g. IceCube) South means the Greenwich meridian) \n");
579 TString saxes[3]={"Local X-axis","Local Y-axis","Local Z-axis"};
580 for (Int_t i=0; i<5; i+=2)
581 {
582 printf(" %-s : zenith=",saxes[i/2].Data()); PrintAngle(fAxes[i],"deg",u,3,kTRUE);
583 printf(" | phi="); PrintAngle(fAxes[i+1],"deg",u,3,kTRUE);
584 printf("\n");
585 }
586 printf(" Lab time offset w.r.t. UT : "); PrintTime(fToffset,12);
587 printf("\n");
588
589 // UT and Local time info
590 Date(mode,fToffset);
591
592 // Add the UTC and TAI related date/time information if requested
593 if (utc && mode!=4) Date(4);
594
595 if (fTscmode)
596 {
597 printf(" ------------------ Time scrambling ----------------- \n");
598 if (fTscmode<0)
599 {
600 printf(" *** Scrambling is applied only for off-source patch (background) data generation in MatchBurstData() *** \n");
601 printf(" *** The actual stored source and measurement data are not modified *** \n");
602 printf("\n");
603 }
604 if (abs(fTscmode)==1)
605 {
606 printf(" *** Each obtained time difference will be scrambled (mode %-i) *** \n",fTscmode);
607 printf(" *** The angular differences are not affected *** \n");
608 printf(" --> Tailored for scrambling entries in a specific time window without affecting \n");
609 printf(" the event selection based on angular separation w.r.t. a source. \n");
610 }
611 if (abs(fTscmode)==2)
612 {
613 if (fTscmode>0)
614 {
615 printf(" *** Each measurement is stored with a scrambled timestamp (mode %-i) *** \n",fTscmode);
616 printf(" *** The data of the sources are not modified *** \n");
617 printf(" *** Off-source (background) data : At each source matching, the measurement is given a new scrambled fake timestamp *** \n");
618 printf(" --> Tailored for blind analyses without access to the unblinded measurement data \n");
619 }
620 else
621 {
622 printf(" *** At each source matching, the measurement is given a new scrambled fake timestamp (mode %-i) *** \n",fTscmode);
623 }
624 printf(" --> Possible patterns in the distribution of sources on the sky will stay intact \n");
625 }
626 if (abs(fTscmode)==3)
627 {
628 printf(" *** At each measurement matching, the source is retrieved from the storage with a scrambled fake timestamp (mode %-i) *** \n",fTscmode);
629 printf(" *** The measurements are not affected --> Detection efficiency is unaltered *** \n");
630 printf(" --> Both time and angular differences will be scrambled \n");
631 printf(" --> Possible patterns in the distribution of sources on the sky will be washed out \n");
632 }
633 TString sx="offsets";
634 if (abs(fTscmode)==1) sx="differences";
635 printf(" Time %-s are randomly drawn from the interval [%-g,%-g] sec. \n",sx.Data(),fTscmin,fTscmax);
636 if (fTscfunc)
637 {
638 printf(" Randomising TF1 function %-s is used. \n",fTscfunc->GetName());
639 }
640 else
641 {
642 printf(" Uniform randomisation is used. \n");
643 }
644 }
645
646 if (fRscmode)
647 {
648 printf(" ------------------ Position scrambling ------------------ \n");
649 if (fRscmode<0)
650 {
651 printf(" *** Scrambling is applied only for off-source patch (background) data generation in MatchBurstData() *** \n");
652 printf(" *** The actual stored source and measurement data are not modified *** \n");
653 }
654 else
655 {
656 printf(" *** The data of the sources and the measurement timestamps are not modified *** \n");
657 }
658 printf("\n");
659
660 if (abs(fRscmode)==1)
661 {
662 printf(" *** Each obtained angular difference will be scrambled (mode %-i) *** \n",fRscmode);
663 printf(" *** The time differences are not affected *** \n");
664 printf(" ---> Tailored for scrambling entries within a specific angular range w.r.t. a source,");
665 printf(" without affecting the event selection based on the time difference w.r.t. a transient source. \n");
666 printf(" Angular differences are randomly drawn from the interval [%-g,%-g] degrees. \n",fDscmin,fDscmax);
667 if (fDscfunc)
668 {
669 printf(" Randomising TF1 function %-s is used. \n",fDscfunc->GetName());
670 }
671 else
672 {
673 printf(" Homogeneous solid angle randomisation is used. \n");
674 }
675 }
676
677 if (fRscmode==2)
678 {
679 printf(" *** Each measurement is stored with a scrambled fake local position (mode %-i) *** \n",fRscmode);
680 printf(" *** Off-source (background) data : At each source matching, the measurement is given a new scrambled fake local position *** \n");
681 printf(" --> Tailored for blind analyses without access to the unblinded measurement data \n");
682 }
683
684 if (abs(fRscmode)==3 || fRscmode==-2)
685 {
686 printf(" *** At each source matching, the measurement is given a new scrambled fake local position (mode %-i) *** \n",fRscmode);
687 }
688
689 if (abs(fRscmode)>1)
690 {
691 printf(" The local coordinates (r,theta,phi) of the measurement are modified to (r+dr,theta+dtheta,phi+dphi) with : \n");
692
693 printf(" dr is randomly drawn from the interval [%-g,%-g] \n",fDscmin,fDscmax);
694 if (fDscfunc)
695 {
696 printf(" Randomising TF1 function %-s is used. \n",fDscfunc->GetName());
697 }
698 else
699 {
700 printf(" Uniform randomisation is used. \n");
701 }
702
703 printf(" dtheta is randomly drawn from the interval [%-g,%-g] degrees. \n",fThetascmin,fThetascmax);
704 if (fThetascfunc)
705 {
706 printf(" Randomising TF1 function %-s is used. \n",fThetascfunc->GetName());
707 }
708 else
709 {
710 printf(" Uniform cos(theta) randomisation is used. \n");
711 }
712
713 printf(" dphi is randomly drawn from the interval [%-g,%-g] degrees. \n",fPhiscmin,fPhiscmax);
714 if (fPhiscfunc)
715 {
716 printf(" Randomising TF1 function %-s is used. \n",fPhiscfunc->GetName());
717 }
718 else
719 {
720 printf(" Uniform phi randomisation is used. \n");
721 }
722 }
723 }
724
725 printf(" ------------------ \n");
726 if (fRan)
727 {
728 Int_t iseed,cnt1,cnt2;
729 GetRandomiser(iseed,cnt1,cnt2);
730 cout << " *** Current settings of the internal NcRandom randomiser : iseed=" << iseed << " cnt1=" << cnt1 << " cnt2=" << cnt2 << endl;
731 }
732 else
733 {
734 cout << " *** The internal NcRandom randomiser is currently not intialised ***" << endl;
735 cout << " Automatic initialisation will be performed with the actual timestamp at the first random number request." << endl;
736 cout << " This will ensure different random sequences for different NcAstrolab instances." << endl;
737 cout << " To obtain reproducible scrambled results, please invoke SetRandomiser() before the first SetSignal() invokation." << endl;
738 }
739 printf(" ------------------ \n");
740}
741
743{
764
765 fLabPos.SetPosition(p);
766
767 // Determine local time offset in fractional hours w.r.t. UT.
768 Double_t vec[3];
769 p.GetVector(vec,"sph","deg");
770 Double_t l=vec[2];
771 fToffset=l/15.;
772}
773
774void NcAstrolab::SetLabPosition(Double_t l,Double_t b,TString u)
775{
808
809 Double_t r=1,theta=0,phi=0;
810
811 l=ConvertAngle(l,u,"deg");
812 b=ConvertAngle(b,u,"deg");
813
814 Double_t offset=90.;
815
816 theta=offset-b;
817 phi=l;
818
819 Double_t p[3]={r,theta,phi};
820 fLabPos.SetPosition(p,"sph","deg");
821
822 // Local time offset in fractional hours w.r.t. UT.
823 fToffset=l/15.;
824}
825
826void NcAstrolab::SetExperiment(TString name,Int_t id)
827{
866
867 fExperiment="User";
868 fLabId=0;
869
870 Double_t l=0; // Longitude
871 Double_t b=0; // Lattitude
872
873 if (name=="User")
874 {
875 SetNameTitle("User","Virtual Lab for general use");
876 SetLabPosition(0,90,"deg"); // North Pole
877 // Right handed local grid frame has X-South (to Greenwich), Y-East and Z-Zenith
878 // which is the same as the Master Reference Frame (MRF)
879 SetLocalFrame(90,0,90,90,0,0);
880 fExperiment=name;
881 fLabId=id;
882 return;
883 }
884
885 if (name=="Greenwich")
886 {
887 // Exact location : 51d 28' 36.6672" (N) and 0d 0' 1.8000" (W)
888 SetNameTitle("Greenwich","The Royal Observatory in the UK");
889 l=-0.000500;
890 b=51.476852;
891 SetLabPosition(l,b,"deg"); // South Pole
892 // Right handed Greenwich local grid frame has X-South, Y-East and Z-Zenith
893 // which is the same as the Master Reference Frame (MRF)
894 SetLocalFrame(90,0,90,90,0,0);
895 fExperiment=name;
896 return;
897 }
898
899 if (name=="Amanda")
900 {
901 SetNameTitle("Amanda","Antarctic Muon And Neutrino Detector Array");
902 SetLabPosition(0,-90,"deg"); // South Pole
903 // Right handed Amanda local grid frame has Y-North (to Greenwich), X-East and Z-Zenith
904 SetLocalFrame(90,90,90,180,0,0);
905 fExperiment=name;
906 return;
907 }
908
909 if (name=="IceCube")
910 {
911 // Exact location : 89d 59' 23.977" (S) and 63d 37' 21.432" (W)
912 SetNameTitle("IceCube","The South Pole Neutrino Observatory");
913 l=-63.453056;
914 b=-89.99;
915 SetLabPosition(l,b,"deg"); // South Pole
916 // Right handed IceCube local grid frame has Y-North (to Greenwich), X-East and Z-Zenith
917 SetLocalFrame(90,90.+l,90,180.+l,0,0);
918 fExperiment=name;
919 return;
920 }
921
922 if (name=="WSRT")
923 {
924 SetNameTitle("WSRT","The Westerbork Synthesis Radio Telescope");
925 SetLabPosition(63612.74,525454.33,"dms");
926 // Right handed local grid frame has X-South, Y-East and Z-Zenith
927 // which is the same as the Master Reference Frame (MRF)
928 SetLocalFrame(90,0,90,90,0,0);
929 fExperiment=name;
930 return;
931 }
932
933 if (name=="Astron")
934 {
935 SetNameTitle("Astron","The Netherlands Institute for Radio Astronomy");
936 SetLabPosition(62346.23,524843.99,"dms");
937 // Right handed local grid frame has X-South, Y-East and Z-Zenith
938 // which is the same as the Master Reference Frame (MRF)
939 SetLocalFrame(90,0,90,90,0,0);
940 fExperiment=name;
941 return;
942 }
943
944 if (name=="ARA")
945 {
946 SetNameTitle("ARA","The Askaryan Radio Array at the South Pole");
947 SetLabPosition(0,-90,"deg"); // South Pole
948 // Right handed ARA local grid frame has Y-North (to Greenwich), X-East and Z-Zenith
949 SetLocalFrame(90,90,90,180,0,0);
950 fExperiment=name;
951 return;
952 }
953
954 if (name=="RNO-G")
955 {
956 SetNameTitle("RNO-G","The Greenland Radio Neutrino Observatory at Summit Station");
957 // Use the location of the Big House as global location
958 l=-38.4604;
959 b=72.57889;
960
961 // The locations of the various stations
962 Int_t ids[35]={11,12,13,14,15,16,17,21,22,23,24,25,26,27,33,34,35,36,37,44,45,46,47,54,55,56,57,64,65,66,67,74,75,76,77};
963 Float_t ls[35]={-38.5023,-38.4962,-38.4901,-38.4841,-38.4780,-38.4719,-38.4657,-38.4660,-38.4599,-38.4538,-38.4477,-38.4416,-38.4355,-38.4293, /*last is 27*/
964 -38.4175,-38.4114,-38.4053,-38.3991,-38.3930,-38.3751,-38.3689,-38.3627,-38.3566,-38.3388,-38.3326,-38.3264,-38.3202,-38.3025, /*last is 64*/
965 -38.2963,-38.2900,-38.2838,-38.2662,-38.2599,-38.2537,-38.2474};
966 Float_t bs[35]={72.58923,72.60009,72.61095,72.62181,72.63267,72.64353,72.65439,72.58741,72.59827,72.60912,72.61998,72.63084,72.64170,72.65256, /*last is 27*/
967 72.60729,72.61815,72.62901,72.63987,72.65073,72.61631,72.62717,72.63803,72.64889,72.61447,72.62533,72.63618,72.64704,72.61262, /*last is 64*/
968 72.62347,72.63433,72.64518,72.61076,72.62161,72.63247,72.64332};
969
970 // Select a specific station, if requested
971 if (id)
972 {
973 for (Int_t i=0; i<35; i++)
974 {
975 if (id==ids[i])
976 {
977 l=ls[i];
978 b=bs[i];
979 fLabId=id;
980 break;
981 }
982 }
983 }
984
985 // Set the selected location
986 SetLabPosition(l,b,"deg"); // Summit Station
987 // Right handed RNO-G local grid frame has Y-North, X-East and Z-Zenith
988 SetLocalFrame(90,90,90,180,0,0);
989 fExperiment=name;
990 return;
991 }
992
993 if (name=="ARCA")
994 {
995 SetNameTitle("ARCA","The KM3NeT/ARCA Neutrino detector near Sicily");
996 SetLabPosition(155842.25,361748.34,"dms");
997 // Right handed ARCA local grid frame has Y-North, X-East and Z-Zenith
998 SetLocalFrame(90,90,90,180,0,0);
999 fExperiment=name;
1000 return;
1001 }
1002
1003 cout << " *" << ClassName() << "::SetExperiment* Unsupported experiment name : " << name.Data() << endl;
1004 printf(" Experiment is set to %-s with detector identifier %-i \n",fExperiment.Data(),fLabId);
1005}
1006
1008{
1018
1019 fToffset=dt;
1020}
1021
1023{
1032
1033 return fLabPos;
1034}
1035
1036void NcAstrolab::GetLabPosition(Double_t& l,Double_t& b,TString u) const
1037{
1053
1054 Double_t pi=acos(-1.);
1055
1056 Double_t offset=90.;
1057 if (u=="rad") offset=pi/2.;
1058
1059 Double_t p[3];
1060 fLabPos.GetPosition(p,"sph",u);
1061 b=offset-p[1];
1062 l=p[2];
1063}
1064
1066{
1072
1073 return fExperiment;
1074}
1075
1077{
1083
1084 return fLabId;
1085}
1086
1088{
1096
1097 return fToffset;
1098}
1099
1100void NcAstrolab::SetRandomiser(Int_t iseed,Int_t cnt1,Int_t cnt2,NcTimestamp* ts)
1101{
1145
1146 if (!ts) ts=(NcTimestamp*)this;
1147
1148 if (fRan) delete fRan;
1149
1150 fRan=new NcRandom(iseed,cnt1,cnt2,ts);
1151}
1152
1153NcRandom* NcAstrolab::GetRandomiser(Int_t& iseed,Int_t& cnt1,Int_t& cnt2) const
1154{
1164
1165 iseed=-1;
1166 cnt1=-1;
1167 cnt2=-1;
1168
1169 if (!fRan) return 0;
1170
1171 iseed=fRan->GetSeed();
1172 cnt1=fRan->GetCnt1();
1173 cnt2=fRan->GetCnt2();
1174
1175 return fRan;
1176}
1177
1178void NcAstrolab::SetMaxDt(Double_t s)
1179{
1191
1192 fMaxDt=s;
1193}
1194
1195Double_t NcAstrolab::GetMaxDt() const
1196{
1206
1207 return fMaxDt;
1208}
1209
1211{
1220
1221 Double_t h=GetLT(fToffset);
1222 return h;
1223}
1224
1226{
1238
1239 Double_t h=GetLMST(fToffset);
1240 return h;
1241}
1242
1244{
1256
1257 Double_t h=GetLAST(fToffset);
1258 return h;
1259}
1260
1261void NcAstrolab::PrintAngle(Double_t a,TString in,TString out,Int_t ndig,Bool_t align) const
1262{
1298
1299 Double_t b=ConvertAngle(a,in,out);
1300
1301 if (out=="deg" || out=="rad")
1302 {
1303 if (align)
1304 {
1305 printf("%*.*f %-s",5+ndig,ndig,b,out.Data());
1306 }
1307 else
1308 {
1309 printf("%-.*f %-s",ndig,b,out.Data());
1310 }
1311 return;
1312 }
1313
1314 Double_t epsilon=1.e-12; // Accuracy in (arc)seconds
1315 Int_t word=0,ddd=0,hh=0,mm=0,ss=0;
1316 Double_t s;
1317
1318 if (out=="dms")
1319 {
1320 word=Int_t(b);
1321 word=abs(word);
1322 ddd=word/10000;
1323 word=word%10000;
1324 mm=word/100;
1325 ss=word%100;
1326 s=fabs(b)-Double_t(ddd*10000+mm*100+ss);
1327 if (s>(1.-epsilon))
1328 {
1329 s=0.;
1330 ss++;
1331 }
1332 while (ss>=60)
1333 {
1334 ss-=60;
1335 mm++;
1336 }
1337 while (mm>=60)
1338 {
1339 mm-=60;
1340 ddd++;
1341 }
1342 while (ddd>=360)
1343 {
1344 ddd-=360;
1345 }
1346 if (b<0) ddd=-ddd;
1347 s+=double(ss);
1348 if (align)
1349 {
1350 if (!ddd && b<0)
1351 {
1352 printf(" -0d %02i' %0*.*f\"",mm,3+ndig,ndig,s);
1353 }
1354 else
1355 {
1356 printf("%4id %02i' %0*.*f\"",ddd,mm,3+ndig,ndig,s);
1357 }
1358 }
1359 else
1360 {
1361 if (!ddd && b<0)
1362 {
1363 printf("-0d %-i' %-.*f\"",mm,ndig,s);
1364 }
1365 else
1366 {
1367 printf("%-id %-i' %-.*f\"",ddd,mm,ndig,s);
1368 }
1369 }
1370 return;
1371 }
1372
1373 if (out=="hms")
1374 {
1375 word=Int_t(b);
1376 word=abs(word);
1377 hh=word/10000;
1378 word=word%10000;
1379 mm=word/100;
1380 ss=word%100;
1381 s=fabs(b)-Double_t(hh*10000+mm*100+ss);
1382 if (s>(1.-epsilon))
1383 {
1384 s=0.;
1385 ss++;
1386 }
1387 while (ss>=60)
1388 {
1389 ss-=60;
1390 mm++;
1391 }
1392 while (mm>=60)
1393 {
1394 mm-=60;
1395 hh++;
1396 }
1397 while (hh>=24)
1398 {
1399 hh-=24;
1400 }
1401 if (b<0) hh=-hh;
1402 s+=double(ss);
1403 if (align)
1404 {
1405 if (!hh && b<0)
1406 {
1407 printf(" -0h %02im %0*.*fs",mm,3+ndig,ndig,s);
1408 }
1409 else
1410 {
1411 printf("%3ih %02im %0*.*fs",hh,mm,3+ndig,ndig,s);
1412 }
1413 }
1414 else
1415 {
1416 if (!hh && b<0)
1417 {
1418 printf("-0h %-im %-.*fs",mm,ndig,s);
1419 }
1420 else
1421 {
1422 printf("%-ih %-im %-.*fs",hh,mm,ndig,s);
1423 }
1424 }
1425 return;
1426 }
1427}
1428
1429NcSignal* NcAstrolab::SetSignal(Nc3Vector* r,TString frame,TString mode,NcTimestamp* ts,Int_t jref,TString name,Int_t type)
1430{
1502
1503 // Cope with the (obsolete) jref=0 specification
1504 if (!jref)
1505 {
1506 type=1;
1507 jref=1;
1508 delete fSigs;
1509 fSigs=0;
1510 }
1511
1512 if (!r) return 0;
1513
1514 if (!r->HasVector()) return 0;
1515
1516 if (frame!="equ" && frame!="gal" && frame!="ecl" && frame!="hor" && frame!="icr" && frame!="loc") return 0;
1517
1518 if (frame=="equ" && mode!="M" && mode!="m" && mode!="T" && mode!="t" && mode!="B" && mode!="b" && mode!="J" && mode!="j") return 0;
1519
1520 NcSignal* sx=0;
1521
1522 if (!ts) ts=(NcTimestamp*)this;
1523
1524 // Make a local copy of the timestamp to make sure that the newly stored
1525 // signal will never contain the Tree with the UTCparameter data.
1526 NcTimestamp ts2;
1527 Int_t mjd=0;
1528 Int_t isec=0;
1529 Int_t ins=0;
1530 Int_t ips=0;
1531 ts->GetMJD(mjd,isec,ins);
1532 ips=ts->GetPs();
1533 ts2.SetMJD(mjd,isec,ins,ips);
1534
1535 Double_t vec[3];
1536 vec[0]=r->GetX(1,"sph","rad");
1537 vec[1]=r->GetX(2,"sph","rad");
1538 vec[2]=r->GetX(3,"sph","rad");
1539 Nc3Vector q;
1540 q.SetVector(vec,"sph","rad");
1541
1542 // Recursive invokation in case of local coordinates
1543 if (frame=="loc")
1544 {
1545 // Convert to horizontal coordinates
1546 q=q.GetUnprimed(&fL);
1547
1548 // Store the signal
1549 sx=SetSignal(&q,"hor",mode,&ts2,jref,name,type);
1550 return sx;
1551 }
1552
1553 // If needed, initialise the randomiser with a "date/time driven" seed
1554 // using the timestamp of the moment of this invokation of the member function.
1555 // This will ensure different random sequences if the user repeats analyses
1556 // with identical measurements and reference signals without explicit initialisation
1557 // of the randomiser by the user at the start of the analysis.
1558 if (!fRan && type && (fTscmode==2 || fRscmode==2)) fRan=new NcRandom(-1);
1559
1560 // Local timestamp copy to allow time scrambling
1561 NcTimestamp tx(ts2);
1562
1563 // Perform time scrambling (measurements only) if requested
1564 if (type && fTscmode==2)
1565 {
1566 Double_t dt=0;
1567
1568 // Allow for specific offset studies
1569 if (fTscmin==fTscmax) dt=fTscmin;
1570
1571 // Go for randomly scrambled values
1572 if (fTscfunc)
1573 {
1574 if (fTscmax>fTscmin)
1575 {
1576 dt=fTscfunc->GetRandom(fTscmin,fTscmax);
1577 }
1578 }
1579 else
1580 {
1581 if (fTscmax>fTscmin) dt=fRan->Uniform(fTscmin,fTscmax);
1582 }
1583 tx.AddSec(dt);
1584 }
1585
1586 // Construct the corresponding ICRS position vector to be stored
1587 if (frame=="equ")
1588 {
1589 // Convert to "mean" values at specified epoch
1590 if (mode=="T" || mode=="t")
1591 {
1592 SetNmatrix(&tx);
1593 q=q.GetUnprimed(&fN);
1594 }
1595
1596 // Convert to "mean" values at J2000
1597 if (mode=="T" || mode=="t" || mode=="M" || mode=="m")
1598 {
1599 SetPmatrix(&tx);
1600 }
1601 else
1602 {
1603 NcTimestamp te;
1604 if (mode=="B" || mode=="b") te.SetEpoch(1950,"B");
1605 if (mode=="J" || mode=="j") te.SetEpoch(2000,"J");
1606 SetPmatrix(&te);
1607 }
1608 q=q.GetUnprimed(&fP);
1609
1610 // Convert to ICRS values
1611 if (!fBias) SetBmatrix();
1612 q=q.GetUnprimed(&fB);
1613 }
1614
1615 if (frame=="gal")
1616 {
1617 // Convert to J2000 equatorial mean coordinates
1618 if (fGal != 2) SetGmatrix("J");
1619 q=q.GetUnprimed(&fG);
1620
1621 // Convert to ICRS values
1622 if (!fBias) SetBmatrix();
1623 q=q.GetUnprimed(&fB);
1624 }
1625
1626 if (frame=="ecl")
1627 {
1628 // Convert to mean equatorial values at specified epoch
1629 SetEmatrix(&tx);
1630 q=q.GetUnprimed(&fE);
1631
1632 // Convert to "mean" values at J2000
1633 SetPmatrix(&tx);
1634 q=q.GetUnprimed(&fP);
1635
1636 // Convert to ICRS values
1637 if (!fBias) SetBmatrix();
1638 q=q.GetUnprimed(&fB);
1639 }
1640
1641 if (frame=="hor")
1642 {
1643 // Convert to "true" equatorial values at the specified timestamp
1644 SetHmatrix(&tx);
1645 q=q.GetUnprimed(&fH);
1646
1647 // Convert to "mean" values at specified timestamp
1648 SetNmatrix(&tx);
1649 q=q.GetUnprimed(&fN);
1650
1651 // Convert to "mean" values at J2000
1652 SetPmatrix(&tx);
1653 q=q.GetUnprimed(&fP);
1654
1655 // Convert to ICRS values
1656 if (!fBias) SetBmatrix();
1657 q=q.GetUnprimed(&fB);
1658 }
1659
1660 // Store the signal in ICRS coordinates
1661 Int_t size=0;
1662 Int_t jmax=0;
1663 Int_t jlast=0;
1664 if (type) // Storage of a measurement
1665 {
1666 NcSignal* sxsig=0;
1667 if (!fSigs)
1668 {
1669 fSigs=new TObjArray();
1670 fSigs->SetOwner();
1671 }
1672 // Expand array size if needed
1673 size=fSigs->GetSize();
1674 jmax=size-1;
1675 jlast=fSigs->GetLast();
1676 if (jref>0)
1677 {
1678 if (jref>size) fSigs->Expand(jref);
1679 }
1680 else
1681 {
1682 if (jlast==jmax) fSigs->Expand(size+1);
1683 }
1684 sxsig=GetSignal(jref,type);
1685 if (!sxsig)
1686 {
1687 sxsig=new NcSignal();
1688 }
1689 else
1690 {
1691 sxsig->Reset(1);
1692 }
1693 if (name=="") // Generate a corresponding measurement name
1694 {
1695 fNen[1]++;
1696 name="Meas";
1697 name+=fNen[1];
1698 name+="#";
1699 }
1700 sxsig->SetName(name);
1701 sxsig->SetTitle("Observed event in ICRS coordinates");
1702 sxsig->SetTimestamp(tx);
1703 sxsig->SetPosition(q);
1704 if (jref<0)
1705 {
1706 fSigs->Add(sxsig);
1707 }
1708 else
1709 {
1710 fSigs->AddAt(sxsig,jref-1);
1711 }
1712 sx=sxsig;
1713 }
1714 else // Storage of a reference signal
1715 {
1716 NcSignal* sxref=0;
1717 if (!fRefs)
1718 {
1719 fRefs=new TObjArray();
1720 fRefs->SetOwner();
1721 }
1722 // Expand array size if needed
1723 size=fRefs->GetSize();
1724 jmax=size-1;
1725 jlast=fRefs->GetLast();
1726 if (jref>0)
1727 {
1728 if (jref>size) fRefs->Expand(jref);
1729 }
1730 else
1731 {
1732 if (jlast==jmax) fRefs->Expand(size+1);
1733 }
1734 sxref=GetSignal(jref,type);
1735 if (!sxref)
1736 {
1737 sxref=new NcSignal();
1738 }
1739 else
1740 {
1741 sxref->Reset(1);
1742 }
1743 if (name=="") // Generate a corresponding reference name
1744 {
1745 fNen[0]++;
1746 name="Ref";
1747 name+=fNen[0];
1748 name+="#";
1749 }
1750 sxref->SetName(name);
1751 sxref->SetTitle("Reference event in ICRS coordinates");
1752 sxref->SetTimestamp(tx);
1753 sxref->SetPosition(q);
1754 if (jref<0)
1755 {
1756 fRefs->Add(sxref);
1757 }
1758 else
1759 {
1760 fRefs->AddAt(sxref,jref-1);
1761 }
1762 sx=sxref;
1763 }
1764
1765 if (fRscmode !=2 || !type) return sx;
1766
1768 // Perform position scrambling (measurements only) if requested //
1770
1771 // Get the measurement in local coordinates
1772 Int_t index=fSigs->IndexOf(sx);
1773 index++; // First storage is at index=1 and not index=0
1774 GetSignal(q,"loc",mode,&tx,index,type);
1775
1776 q.GetVector(vec,"sph","deg");
1777
1778 Double_t dd=0;
1779 Double_t dtheta=0;
1780 Double_t dphi=0;
1781
1782 // Allow specific offset studies
1783 if (fDscmin==fDscmax) dd=fDscmin;
1784 if (fThetascmin==fThetascmax) dtheta=fThetascmin;
1785 if (fPhiscmin==fPhiscmax) dphi=fPhiscmin;
1786
1787 // Go for randomly scrambled values
1788 if (fDscfunc)
1789 {
1790 if (fDscmax>fDscmin)
1791 {
1792 dd=fDscfunc->GetRandom(fDscmin,fDscmax);
1793 }
1794 }
1795 else
1796 {
1797 if (fDscmax>fDscmin) dd=fRan->Uniform(fDscmin,fDscmax);
1798 }
1799
1800 if (fThetascfunc)
1801 {
1803 {
1804 dtheta=fThetascfunc->GetRandom(fThetascmin,fThetascmax);
1805 }
1806 }
1807 else if (fThetascmax>fThetascmin)
1808 {
1809 Double_t pi=acos(-1.);
1810 Float_t cosmin=cos(fThetascmin*pi/180.);
1811 Float_t cosmax=cos(fThetascmax*pi/180.);
1812 if (cosmin>cosmax)
1813 {
1814 Float_t temp=cosmin;
1815 cosmin=cosmax;
1816 cosmax=temp;
1817 }
1818 Double_t cosang=fRan->Uniform(cosmin,cosmax);
1819 dtheta=acos(cosang)*180./pi;
1820 }
1821
1822 if (fPhiscfunc)
1823 {
1824 if (fPhiscmax>fPhiscmin)
1825 {
1826 dphi=fPhiscfunc->GetRandom(fPhiscmin,fPhiscmax);
1827 }
1828 }
1829 else
1830 {
1831 if (fPhiscmax>fPhiscmin) dphi=fRan->Uniform(fPhiscmin,fPhiscmax);
1832 }
1833
1834 vec[0]+=dd;
1835 if (vec[0]<=0) vec[0]=1e-20; // Keep a physical situation
1836 vec[1]+=dtheta;
1837 vec[2]+=dphi;
1838 q.SetVector(vec,"sph","deg");
1839
1841 // Construct the corresponding ICRS position vector to be stored //
1843
1844 // Convert to horizontal coordinates
1845 q=q.GetUnprimed(&fL);
1846
1847 // Convert to "true" equatorial values at the specified timestamp
1848 SetHmatrix(&tx);
1849 q=q.GetUnprimed(&fH);
1850
1851 // Convert to "mean" values at specified timestamp
1852 SetNmatrix(&tx);
1853 q=q.GetUnprimed(&fN);
1854
1855 // Convert to "mean" values at J2000
1856 SetPmatrix(&tx);
1857 q=q.GetUnprimed(&fP);
1858
1859 // Convert to ICRS values
1860 if (!fBias) SetBmatrix();
1861 q=q.GetUnprimed(&fB);
1862
1863 // Store the measurement position
1864 sx->SetPosition(q);
1865
1866 return sx;
1867}
1868
1869Int_t NcAstrolab::SetSolarSystem(TString name,NcTimestamp* ts,Int_t type)
1870{
1896
1897 // Only geocentric positions are allowed
1898 if (name.Contains("*")) return 0;
1899
1900 if (!ts) ts=(NcTimestamp*)this;
1901
1902 Double_t lx=0; // Geocentric ecliptic longitude of the object in degrees
1903 Double_t bx=0; // Geocentric ecliptic latitude of the object in degrees
1904 Double_t rx=0; // Distance (AU for planets, km for the Moon) between the object and the Earth.
1905
1906 Int_t set=0; // Flag to indicate that a location has been set
1907
1908 ts->Almanac(0,0,0,0,name,&lx,&bx,&rx);
1909
1910 if (rx>0) set=1;
1911
1912 // Replace c.q. store the object data as a reference or measured signal according to "type".
1913 // In case the object wasn't stored yet, jref=-1 and the object will be
1914 // added to the list of stored signals of "type".
1915 Int_t jref=GetSignalIndex(name,type);
1916 if (set && jref) SetSignal(rx,lx,"deg",bx,"deg","ecl",ts,jref,"M",name,type);
1917
1918 return set;
1919}
1920
1921NcSignal* NcAstrolab::SetSignal(Double_t d,Double_t a,TString au,Double_t b,TString bu,TString frame,NcTimestamp* ts,Int_t jref,TString mode,TString name,Int_t type)
1922{
2001
2002 // Assure physical value for the norm of the location vector
2003 if (d<=0) d=1;
2004
2005 // Convert angular coordinates to fractional degrees.
2006 a=ConvertAngle(a,au,"deg");
2007 b=ConvertAngle(b,bu,"deg");
2008
2009 Nc3Vector r;
2010 Double_t vec[3]={0,0,0};
2011 vec[0]=d;
2012
2013 // Equatorial coordinates
2014 if (frame=="equ")
2015 {
2016 if (mode!="M" && mode!="m" && mode!="T" && mode!="t" && mode!="B" && mode!="b" && mode!="J" && mode!="j") return 0;
2017 vec[1]=90.-b;
2018 vec[2]=a;
2019 }
2020
2021 // Galactic coordinates
2022 if (frame=="gal")
2023 {
2024 vec[1]=90.-b;
2025 vec[2]=a;
2026 }
2027
2028 // Geocentric ecliptic coordinates
2029 if (frame=="ecl")
2030 {
2031 vec[1]=90.-b;
2032 vec[2]=a;
2033 }
2034
2035 // Horizontal coordinates
2036 if (frame=="hor")
2037 {
2038 vec[1]=b;
2039 vec[2]=180.-a;
2040 }
2041
2042 // ICRS coordinates
2043 if (frame=="icr")
2044 {
2045 vec[1]=90.-b;
2046 vec[2]=a;
2047 }
2048
2049 // Local coordinates
2050 if (frame=="loc" || frame=="pdir")
2051 {
2052 vec[1]=a;
2053 vec[2]=b;
2054 }
2055
2056 if (!ts) ts=(NcTimestamp*)this;
2057
2058 r.SetVector(vec,"sph","deg");
2059
2060 // Revert momentum direction in order to get the source direction
2061 if (frame=="pdir")
2062 {
2063 r*=-1.;
2064 frame="loc";
2065 }
2066
2067 NcSignal* sx=SetSignal(&r,frame,mode,ts,jref,name,type);
2068 return sx;
2069}
2070
2071NcSignal* NcAstrolab::SetSignal(Double_t d,Double_t a,TString au,Double_t b,TString bu,TString frame,TString s,Double_t e,Int_t jref,TString mode,TString name,Int_t type)
2072{
2154
2155 NcTimestamp tx;
2156 tx.SetEpoch(e,s);
2157
2158 NcSignal* sx=SetSignal(d,a,au,b,bu,frame,&tx,jref,mode,name,type);
2159 return sx;
2160}
2161
2162Int_t NcAstrolab::SetSourceAttributes(NcSignal* s,Double_t sigmapos,TString u,Double_t z,Double_t T90)
2163{
2190
2191 if (!s) return 0;
2192
2193 Int_t n=3;
2194
2195 if (sigmapos<0)
2196 {
2197 sigmapos=-999;
2198 n--;
2199 }
2200 if (z<0)
2201 {
2202 z=-999;
2203 n--;
2204 }
2205 if (T90<0)
2206 {
2207 T90=-999;
2208 n--;
2209 }
2210
2211 // Convert the position uncertainty into degrees
2212 Double_t sigma=ConvertAngle(sigmapos,u,"deg");
2213
2214 s->AddNamedSlot("csigma");
2215 s->AddNamedSlot("z");
2216 s->AddNamedSlot("T90");
2217 s->SetSignal(sigma,"csigma");
2218 s->SetSignal(z,"z");
2219 s->SetSignal(T90,"T90");
2220
2221 return n;
2222}
2223
2224Double_t NcAstrolab::GetSourceAttributes(NcSignal* s,Float_t* z,Float_t* T90)
2225{
2244
2245 if (!s) return -999;
2246
2247 Double_t sigma=s->GetSignal("csigma");
2248 if (z) *z=s->GetSignal("z");
2249 if (T90) *T90=s->GetSignal("T90");
2250
2251 return sigma;
2252}
2253
2254Int_t NcAstrolab::GetNRefSignals(Int_t mode) const
2255{
2281
2282 Int_t n=GetNsignals(0,mode);
2283 return n;
2284}
2285
2286Int_t NcAstrolab::GetNsignals(Int_t type,Int_t mode) const
2287{
2311
2312 TObjArray* arr=fRefs;
2313 if (type) arr=fSigs;
2314
2315 if (!arr) return 0;
2316
2317 Int_t n=0;
2318 if (!mode)
2319 {
2320 n=arr->GetEntries();
2321 }
2322 else
2323 {
2324 n=arr->GetSize();
2325 }
2326 return n;
2327}
2328
2329NcSignal* NcAstrolab::GetSignal(Nc3Vector& r,TString frame,TString mode,NcTimestamp* ts,Int_t jref,Int_t type)
2330{
2389
2390 r.SetZero();
2391
2392 if (frame!="equ" && frame!="gal" && frame!="ecl" && frame!="hor" && frame!="icr" && frame!="loc") return 0;
2393
2394 if (frame=="equ" && mode!="M" && mode!="m" && mode!="T" && mode!="t" && mode!="B" && mode!="b" && mode!="J" && mode!="j") return 0;
2395
2396 // For backward compatibility
2397 if (!jref)
2398 {
2399 jref=1;
2400 type=1;
2401 }
2402
2403 NcSignal* sx=GetSignal(jref,type);
2404
2405 if (!sx) return 0;
2406
2407 if (!ts) ts=(NcTimestamp*)this;
2408
2409 // Check on maximum time difference
2410 if (fMaxDt>0)
2411 {
2412 NcTimestamp* tx=sx->GetTimestamp();
2413 if (!tx) return 0;
2414 Double_t dt=tx->GetDifference(ts,"s",1);
2415 if (fabs(dt)>fMaxDt) return 0;
2416 }
2417
2418 // Update coordinates for Solar system objects
2419 TString name=sx->GetName();
2420 SetSolarSystem(name,ts,type);
2421
2422 Double_t vec[3];
2423 sx->GetPosition(vec,"sph","rad");
2424 Nc3Vector q;
2425 q.SetVector(vec,"sph","rad");
2426
2427 if (frame=="icr")
2428 {
2429 r.Load(q);
2430 return sx;
2431 }
2432
2433 // Convert from ICRS to equatorial J2000 coordinates
2434 if (!fBias) SetBmatrix();
2435 q=q.GetPrimed(&fB);
2436
2437 if (frame=="equ" && mode!="J" && mode!="j")
2438 {
2439 // Precess to specified timestamp
2440 NcTimestamp ts1;
2441 ts1.SetEpoch(2000,"J");
2442 if (mode!="B" && mode!="b")
2443 {
2444 Precess(q,&ts1,ts);
2445 }
2446 else
2447 {
2448 NcTimestamp ts2;
2449 ts2.SetEpoch(1950,"B");
2450 Precess(q,&ts1,&ts2);
2451 }
2452
2453 // Nutation correction if requested
2454 if (mode=="T" || mode=="t") Nutate(q,ts);
2455 }
2456
2457 if (frame=="gal")
2458 {
2459 // Convert from equatorial J2000 to galactic
2460 if (fGal != 2) SetGmatrix("J");
2461 q=q.GetPrimed(&fG);
2462 }
2463
2464 if (frame=="ecl")
2465 {
2466 // Precess to specified timestamp
2467 NcTimestamp ts1;
2468 ts1.SetEpoch(2000,"J");
2469 Precess(q,&ts1,ts);
2470
2471 // Convert from equatorial to ecliptic coordinates
2472 SetEmatrix(ts);
2473 q=q.GetPrimed(&fE);
2474 }
2475
2476 if (frame=="hor")
2477 {
2478 // Precess to specified timestamp
2479 NcTimestamp ts1;
2480 ts1.SetEpoch(2000,"J");
2481 Precess(q,&ts1,ts);
2482
2483 // Nutation correction
2484 Nutate(q,ts);
2485
2486 // Convert from equatorial to horizontal coordinates
2487 SetHmatrix(ts);
2488 q=q.GetPrimed(&fH);
2489 }
2490
2491 if (frame=="loc")
2492 {
2493 // Get the signal in horizontal coordinates
2494 GetSignal(q,"hor",mode,ts,jref,type);
2495
2496 // Convert from horizontal to local-frame coordinates
2497 q=q.GetPrimed(&fL);
2498 }
2499
2500 r.Load(q);
2501 return sx;
2502}
2503
2504void NcAstrolab::GeoToHeliocentric(Double_t& R,Double_t& B,Double_t& L,NcTimestamp* ts,TString Bu,TString Lu)
2505{
2539
2540 if (!ts) ts=(NcTimestamp*)this;
2541
2542 // Convert the angles into radians
2543 B=ConvertAngle(B,Bu,"rad");
2544 L=ConvertAngle(L,Lu,"rad");
2545
2546 // The Carthesian Geocentric ecliptic coordinates of the object
2547 Double_t xg=R*cos(B)*cos(L);
2548 Double_t yg=R*cos(B)*sin(L);
2549 Double_t zg=R*sin(B);
2550
2551 // Get the Heliocentric ecliptic coordinates of the Earth
2552 Double_t r0,b0,l0;
2553 ts->Almanac(0,0,0,0,"Earth*",&l0,&b0,&r0);
2554
2555 l0=ConvertAngle(l0,"deg","rad");
2556 b0=ConvertAngle(b0,"deg","rad");
2557
2558 Double_t x0=r0*cos(b0)*cos(l0);
2559 Double_t y0=r0*cos(b0)*sin(l0);
2560 Double_t z0=r0*sin(b0);
2561
2562 // The Heliocentric Carthesian ecliptic coordinates of the object
2563 Double_t xh=xg+x0;
2564 Double_t yh=yg+y0;
2565 Double_t zh=zg+z0;
2566
2567 // Convert to Heliocentric distance, latitude and longitude
2568 Double_t Rh=sqrt(xh*xh+yh*yh+zh*zh);
2569 Double_t Bh=atan2(zh,sqrt(xh*xh+yh*yh));
2570 Double_t Lh=atan2(yh,xh);
2571
2572 Double_t twopi=2.*acos(-1.);
2573 while (Lh<0) { Lh+=twopi; }
2574 while (Lh>twopi) { Lh-=twopi; }
2575
2576 // Return the Heliocentric values in the original units
2577 R=Rh;
2578 B=ConvertAngle(Bh,"rad",Bu);
2579 L=ConvertAngle(Lh,"rad",Lu);
2580}
2581
2582void NcAstrolab::HelioToGeocentric(Double_t& R,Double_t& B,Double_t& L,NcTimestamp* ts,TString Bu,TString Lu)
2583{
2617
2618 if (!ts) ts=(NcTimestamp*)this;
2619
2620 // Convert the angles into radians
2621 B=ConvertAngle(B,Bu,"rad");
2622 L=ConvertAngle(L,Lu,"rad");
2623
2624 // The Carthesian Heliocentric ecliptic coordinates of the object
2625 Double_t xh=R*cos(B)*cos(L);
2626 Double_t yh=R*cos(B)*sin(L);
2627 Double_t zh=R*sin(B);
2628
2629 // Get the Heliocentric ecliptic coordinates of the Earth
2630 Double_t r0,b0,l0;
2631 ts->Almanac(0,0,0,0,"Earth*",&l0,&b0,&r0);
2632
2633 l0=ConvertAngle(l0,"deg","rad");
2634 b0=ConvertAngle(b0,"deg","rad");
2635
2636 Double_t x0=r0*cos(b0)*cos(l0);
2637 Double_t y0=r0*cos(b0)*sin(l0);
2638 Double_t z0=r0*sin(b0);
2639
2640 // The Geocentric Carthesian ecliptic coordinates of the object
2641 Double_t xg=xh-x0;
2642 Double_t yg=yh-y0;
2643 Double_t zg=zh-z0;
2644
2645 // Convert to Geocentric distance, latitude and longitude
2646 Double_t Rg=sqrt(xg*xg+yg*yg+zg*zg);
2647 Double_t Bg=atan2(zg,sqrt(xg*xg+yg*yg));
2648 Double_t Lg=atan2(yg,xg);
2649
2650 Double_t twopi=2.*acos(-1.);
2651 while (Lg<0) { Lg+=twopi; }
2652 while (Lg>twopi) { Lg-=twopi; }
2653
2654 // Return the Geocentric values in the original units
2655 R=Rg;
2656 B=ConvertAngle(Bg,"rad",Bu);
2657 L=ConvertAngle(Lg,"rad",Lu);
2658}
2659
2660NcSignal* NcAstrolab::GetSignal(Double_t& d,Double_t& a,TString au,Double_t& b,TString bu,TString frame,NcTimestamp* ts,Int_t jref,TString mode,Int_t type)
2661{
2732
2733 d=0;
2734 a=0;
2735 b=0;
2736
2737 Nc3Vector r;
2738 NcSignal* sx=GetSignal(r,frame,mode,ts,jref,type);
2739
2740 if (!sx) return 0;
2741
2742 // Retrieve the requested (a,d) values in the correct format
2743 Double_t vec[3];
2744 r.GetVector(vec,"sph","deg");
2745
2746 d=vec[0];
2747 if (d<=0) d=1;
2748 b=vec[1];
2749 a=vec[2];
2750
2751 if (frame=="equ" || frame=="gal" || frame=="ecl" || frame=="icr")
2752 {
2753 b=90.-vec[1];
2754 while (b<-90.)
2755 {
2756 b+=90.;
2757 }
2758 while (b>90.)
2759 {
2760 b-=90.;
2761 }
2762 }
2763
2764 if (frame=="hor")
2765 {
2766 a=180.-vec[2];
2767 }
2768
2769 while (a<-360.)
2770 {
2771 a+=360.;
2772 }
2773 while (a>360.)
2774 {
2775 a-=360.;
2776 }
2777
2778 // Interchange a and b to represent theta and phi, respectively, for local coordinates
2779 if (frame=="loc")
2780 {
2781 Double_t temp=a;
2782 a=b;
2783 b=temp;
2784 }
2785
2786 // Convert coordinates to appropriate format
2787 a=ConvertAngle(a,"deg",au);
2788 b=ConvertAngle(b,"deg",bu);
2789
2790 return sx;
2791}
2792
2793NcSignal* NcAstrolab::GetSignal(Double_t& d,Double_t& a,TString au,Double_t& b,TString bu,TString frame,NcTimestamp* ts,TString name,TString mode,Int_t type)
2794{
2866
2867 // Set c.q. update coordinates for Solar system objects
2868 SetSolarSystem(name,ts,type);
2869
2870 NcSignal* sx=0;
2871 Int_t j=GetSignalIndex(name,type);
2872 if (j>=0) sx=GetSignal(d,a,au,b,bu,frame,ts,j,mode,type);
2873 return sx;
2874}
2875
2876NcSignal* NcAstrolab::GetSignal(Double_t& d,Double_t& a,TString au,Double_t& b,TString bu,TString frame,TString s,Double_t e,Int_t jref,TString mode,Int_t type)
2877{
2952
2953 d=0;
2954 a=0;
2955 b=0;
2956
2957 if (s!="B" && s!="b" && s!="J" && s!="j") return 0;
2958
2959 NcTimestamp tx;
2960 tx.SetEpoch(e,s);
2961
2962 NcSignal* sx=GetSignal(d,a,au,b,bu,frame,&tx,jref,mode,type);
2963 return sx;
2964}
2965
2966NcSignal* NcAstrolab::GetSignal(Double_t& d,Double_t& a,TString au,Double_t& b,TString bu,TString frame,TString s,Double_t e,TString name,TString mode,Int_t type)
2967{
3043
3044 // Set c.q. update coordinates for Solar system objects
3045 NcTimestamp tx;
3046 tx.SetEpoch(e,s);
3047 SetSolarSystem(name,&tx,type);
3048
3049 NcSignal* sx=0;
3050 Int_t j=GetSignalIndex(name,type);
3051 if (j>=0) sx=GetSignal(d,a,au,b,bu,frame,s,e,j,mode,type);
3052 return sx;
3053}
3054
3055NcSignal* NcAstrolab::GetSignal(Int_t jref,Int_t type)
3056{
3077
3078 if (jref<0) return 0;
3079
3080 if (!jref) // For backward compatibility
3081 {
3082 jref=1;
3083 type=1;
3084 }
3085
3086 if (!type && !fRefs) return 0;
3087 if (type && !fSigs) return 0;
3088
3089 NcSignal* sx=0;
3090 if (type)
3091 {
3092 if (jref<=fSigs->GetSize()) sx=(NcSignal*)fSigs->At(jref-1);
3093 }
3094 else
3095 {
3096 if (jref<=fRefs->GetSize()) sx=(NcSignal*)fRefs->At(jref-1);
3097 }
3098 return sx;
3099}
3100
3101NcSignal* NcAstrolab::GetSignal(TString name,Int_t type,NcTimestamp* ts)
3102{
3121
3122 NcSignal* sx=0;
3123 Int_t j=GetSignalIndex(name,type);
3124
3125 if (j==-1) // Set and store info for the requested Solar system object if not already stored
3126 {
3127 SetSolarSystem(name,ts,type);
3128 j=GetSignalIndex(name,type);
3129 }
3130
3131 if (j>=0) sx=GetSignal(j,type);
3132 return sx;
3133}
3134
3135Int_t NcAstrolab::RemoveRefSignal(Int_t j,Int_t compress)
3136{
3158
3159 Int_t nrem=0;
3160
3161 if (!fRefs) return 0;
3162
3163 // Clearing of the complete storage
3164 if (!j)
3165 {
3166 nrem=fRefs->GetEntries();
3167 delete fRefs;
3168 fRefs=0;
3169 return nrem;
3170 }
3171
3172 // Removing a specific reference signal
3173 if (j>0 && j<=fRefs->GetSize())
3174 {
3175 TObject* obj=fRefs->RemoveAt(j-1);
3176 if (obj)
3177 {
3178 delete obj;
3179 nrem++;
3180 }
3181 }
3182
3183 // Compression of the storage array
3184 if (compress) fRefs->Compress();
3185
3186 return nrem;
3187}
3188
3189Int_t NcAstrolab::RemoveRefSignal(TString name,Int_t compress)
3190{
3210
3211 Int_t nrem=0;
3212
3213 Int_t j=GetSignalIndex(name);
3214 if (j>0) nrem=RemoveRefSignal(j,compress);
3215
3216 return nrem;
3217}
3218
3219Int_t NcAstrolab::RemoveSignal(Int_t j,Int_t type,Int_t compress)
3220{
3240
3241 Int_t nrem=0;
3242
3243 TObjArray* arr=fRefs;
3244 if (type) arr=fSigs;
3245
3246 if (!arr) return nrem;
3247
3248 // Clearing of the complete "type" storage
3249 if (!j)
3250 {
3251 nrem=arr->GetEntries();
3252 delete arr;
3253 if (type)
3254 {
3255 fSigs=0;
3256 fNen[1]=0;
3257 }
3258 else
3259 {
3260 fRefs=0;
3261 fNen[0]=0;
3262 }
3263 return nrem;
3264 }
3265
3266 // Removing the specified signal
3267 if (j>0 && j<=arr->GetSize())
3268 {
3269 TObject* obj=arr->RemoveAt(j-1);
3270 if (obj)
3271 {
3272 delete obj;
3273 nrem++;
3274 }
3275 }
3276
3277 // Compression of the storage array
3278 if (compress)
3279 {
3280 arr->Compress();
3281 Int_t n=arr->GetEntries();
3282 arr->Expand(n);
3283 }
3284
3285 return nrem;
3286}
3287
3288Int_t NcAstrolab::RemoveSignal(TString name,Int_t type,Int_t compress)
3289{
3312
3313 Int_t nrem=0;
3314
3315 if (name=="") return nrem;
3316
3317 if (name=="*")
3318 {
3319 nrem=RemoveSignal(0,type,compress);
3320 }
3321 else
3322 {
3323 Int_t j=GetSignalIndex(name,type);
3324 if (j>0) nrem=RemoveSignal(j,type,compress);
3325 }
3326
3327 return nrem;
3328}
3329
3330Int_t NcAstrolab::RemoveSignals(TString name,Int_t type,Int_t compress)
3331{
3354
3355 Int_t nrem=0;
3356
3357 if (name=="") return 0;
3358
3359 if (name=="*")
3360 {
3361 nrem=RemoveSignal(0,type,compress);
3362 }
3363 else
3364 {
3365 TObjArray* arr=fRefs;
3366 if (type) arr=fSigs;
3367
3368 if (!arr) return 0;
3369
3370 NcSignal* sx=0;
3371 TString namex="";
3372 Int_t nremx=0;
3373 for (Int_t j=1; j<=arr->GetSize(); j++)
3374 {
3375 sx=GetSignal(j,type);
3376 if (!sx) continue;
3377
3378 namex=sx->GetName();
3379 if (!namex.Contains(name)) continue;
3380
3381 nremx=RemoveSignal(j,type,0);
3382 if (nremx) nrem++;
3383 }
3384
3385 // Compression of the storage array
3386 if (compress)
3387 {
3388 arr->Compress();
3389 Int_t n=arr->GetEntries();
3390 arr->Expand(n);
3391 }
3392 }
3393
3394 return nrem;
3395}
3396
3397Int_t NcAstrolab::GetSignalIndex(TString name,Int_t type)
3398{
3411
3412 if (name=="") return -1;
3413
3414 Int_t index=-1;
3415
3416 TObjArray* arr=fRefs;
3417 if (type) arr=fSigs;
3418
3419 if (!arr) return -1;
3420
3421 for (Int_t i=0; i<arr->GetSize(); i++)
3422 {
3423 NcSignal* sx=(NcSignal*)arr->At(i);
3424 if (!sx) continue;
3425
3426 if (name==sx->GetName())
3427 {
3428 index=i+1;
3429 break;
3430 }
3431 }
3432
3433 return index;
3434}
3435
3437{
3448
3449 if (!s) return -1;
3450
3451 Int_t index=-1;
3452
3453 TObjArray* arr=fRefs;
3454 if (type) arr=fSigs;
3455
3456 if (!arr) return -1;
3457
3458 for (Int_t i=0; i<arr->GetSize(); i++)
3459 {
3460 NcSignal* sx=(NcSignal*)arr->At(i);
3461 if (!sx) continue;
3462
3463 if (sx==s)
3464 {
3465 index=i+1;
3466 break;
3467 }
3468 }
3469
3470 return index;
3471}
3472
3473void NcAstrolab::PrintSignal(TString frame,TString mode,NcTimestamp* ts,Int_t ndig,Int_t jref,TString emode,Int_t type,Bool_t align)
3474{
3553
3554 NcSignal* sx=GetSignal(jref,type);
3555
3556 if (!sx) return;
3557
3558 if (!ts) ts=sx->GetTimestamp();
3559
3560 Nc3Vector r;
3561 GetSignal(r,frame,mode,ts,jref,type);
3562
3563 // Local Hour Angle of the signal
3564 Double_t lha=GetHourAngle("A",ts,jref,type);
3565 TString slha="LAHA";
3566 if (mode=="M" || mode=="m")
3567 {
3568 lha=GetHourAngle("M",ts,jref,type);
3569 slha="LMHA";
3570 }
3571 else if ((mode=="B" || mode=="b" || mode=="J" || mode=="j") && emode=="M")
3572 {
3573 lha=GetHourAngle("M",ts,jref,type);
3574 slha="LMHA";
3575 }
3576
3577 if (frame=="equ")
3578 {
3579 Double_t a,d;
3580 d=90.-r.GetX(2,"sph","deg");
3581 a=r.GetX(3,"sph","rad");
3582 if (mode=="B" || mode=="b") mode="B1950";
3583 if (mode=="J" || mode=="j") mode="J2000";
3584 cout << "Equatorial (" << mode.Data() <<") | a :";
3585 if (!align) {cout << " ";} PrintAngle(a,"rad","hms",ndig,align);
3586 if (!align) {cout << " ";} PrintAngle(a,"rad","deg",ndig,align);
3587 cout << " | b :";
3588 if (!align) {cout << " ";} PrintAngle(d,"deg","dms",ndig,align);
3589 if (!align) {cout << " ";} PrintAngle(d,"deg","deg",ndig,align);
3590 cout << " | " << slha.Data() << " : ";
3591 PrintAngle(lha,"deg","hms",ndig,align);
3592 cout << " "; PrintAngle(lha,"deg","deg",ndig,align);
3593 }
3594
3595 if (frame=="gal")
3596 {
3597 Double_t l,b;
3598 b=90.-r.GetX(2,"sph","deg");
3599 l=r.GetX(3,"sph","deg");
3600 cout << "Galactic | l :";
3601 if (!align) {cout << " ";} PrintAngle(l,"deg","deg",ndig,align);
3602 if (!align) {cout << " ";} PrintAngle(l,"deg","dms",ndig,align);
3603 cout << " | b :";
3604 if (!align) {cout << " ";} PrintAngle(b,"deg","deg",ndig,align);
3605 if (!align) {cout << " ";} PrintAngle(b,"deg","dms",ndig,align);
3606 cout << " | " << slha.Data() << " : ";
3607 PrintAngle(lha,"deg","hms",ndig,align);
3608 cout << " "; PrintAngle(lha,"deg","deg",ndig,align);
3609 }
3610
3611 if (frame=="icr")
3612 {
3613 Double_t l,b;
3614 b=90.-r.GetX(2,"sph","deg");
3615 l=r.GetX(3,"sph","deg");
3616 cout << "ICRS | l :";
3617 if (!align) {cout << " ";} PrintAngle(l,"deg","deg",ndig,align);
3618 if (!align) {cout << " ";} PrintAngle(l,"deg","dms",ndig,align);
3619 cout << " | b :";
3620 if (!align) {cout << " ";} PrintAngle(b,"deg","deg",ndig,align);
3621 if (!align) {cout << " ";} PrintAngle(b,"deg","dms",ndig,align);
3622 cout << " | " << slha.Data() << " : ";
3623 PrintAngle(lha,"deg","hms",ndig,align);
3624 cout << " "; PrintAngle(lha,"deg","deg",ndig,align);
3625 }
3626
3627 if (frame=="ecl")
3628 {
3629 Double_t l,b;
3630 b=90.-r.GetX(2,"sph","deg");
3631 l=r.GetX(3,"sph","deg");
3632 cout << "Geocentric ecliptic | l :";
3633 if (!align) {cout << " ";} PrintAngle(l,"deg","deg",ndig,align);
3634 if (!align) {cout << " ";} PrintAngle(l,"deg","dms",ndig,align);
3635 cout << " | b :";
3636 if (!align) {cout << " ";} PrintAngle(b,"deg","deg",ndig,align);
3637 if (!align) {cout << " ";} PrintAngle(b,"deg","dms",ndig,align);
3638 cout << " | " << slha.Data() << " : ";
3639 PrintAngle(lha,"deg","hms",ndig,align);
3640 cout << " "; PrintAngle(lha,"deg","deg",ndig,align);
3641 }
3642
3643 if (frame=="hor")
3644 {
3645 Double_t alt=90.-r.GetX(2,"sph","deg");
3646 Double_t azi=180.-r.GetX(3,"sph","deg");
3647 while (azi>360)
3648 {
3649 azi-=360.;
3650 }
3651 while (azi<0)
3652 {
3653 azi+=360.;
3654 }
3655 cout << "Horizontal | azi :";
3656 if (!align) {cout << " ";} PrintAngle(azi,"deg","deg",ndig,align);
3657 if (!align) {cout << " ";} PrintAngle(azi,"deg","dms",ndig,align);
3658 cout << " | alt :";
3659 if (!align) {cout << " ";} PrintAngle(alt,"deg","deg",ndig,align);
3660 if (!align) {cout << " ";} PrintAngle(alt,"deg","dms",ndig,align);
3661 cout << " | " << slha.Data() << " : ";
3662 PrintAngle(lha,"deg","hms",ndig,align);
3663 cout << " "; PrintAngle(lha,"deg","deg",ndig,align);
3664 }
3665
3666 if (frame=="loc")
3667 {
3668 Double_t theta=r.GetX(2,"sph","deg");
3669 Double_t phi=r.GetX(3,"sph","deg");
3670 cout << "Local-frame | phi :";
3671 if (!align) {cout << " ";} PrintAngle(phi,"deg","deg",ndig,align);
3672 if (!align) {cout << " ";} PrintAngle(phi,"deg","dms",ndig,align);
3673 cout << " | theta :";
3674 if (!align) {cout << " ";} PrintAngle(theta,"deg","deg",ndig,align);
3675 if (!align) {cout << " ";} PrintAngle(theta,"deg","dms",ndig,align);
3676 cout << " | " << slha.Data() << " : ";
3677 PrintAngle(lha,"deg","hms",ndig,align);
3678 cout << " "; PrintAngle(lha,"deg","deg",ndig,align);
3679 }
3680
3681 cout << " |";
3682
3683 TString name=sx->GetName();
3684 if (name != "") cout << " " << name.Data();
3685}
3686
3687void NcAstrolab::PrintSignal(TString frame,TString mode,NcTimestamp* ts,Int_t ndig,TString name,TString emode,Int_t type,Bool_t align)
3688{
3764
3765 // Set c.q. update coordinates for Solar system objects
3766 SetSolarSystem(name,ts,type);
3767
3768 Int_t j=GetSignalIndex(name,type);
3769 if (j>=0) PrintSignal(frame,mode,ts,ndig,j,emode,type,align);
3770}
3771
3772void NcAstrolab::ListSignals(TString frame,TString mode,Int_t ndig,TString emode,Int_t nmax,Int_t j,Int_t type,NcTimestamp* ts,TString name)
3773{
3845
3846 Int_t iprint=0;
3847 Int_t width=0; // Width for printing of the index
3848 if (nmax>0) width=log10(nmax);
3849 if (nmax<0)
3850 {
3851 Int_t maxref=0;
3852 if (fRefs) maxref=fRefs->GetSize();
3853 Int_t maxsig=0;
3854 if (fSigs) maxsig=fSigs->GetSize();
3855 Int_t maxj=maxref;
3856 if (maxsig>maxj) maxj=maxsig;
3857 if (maxj>0) width=log10(maxj);
3858 }
3859 width++;
3860
3861 NcSignal* sx=0;
3862 NcTimestamp* tx=0;
3863
3864 Int_t dform=1;
3865 if (mode=="T" || mode=="t") dform=-1;
3866 if ((mode=="B" || mode=="b" || mode=="J" || mode=="j") && emode=="T") dform=-1;
3867
3868 if (j>0) sx=GetSignal(j,1);
3869 if (sx)
3870 {
3871 tx=sx->GetTimestamp();
3872 if (!tx) tx=ts;
3873 if (!tx) tx=(NcTimestamp*)this;
3874 printf(" *%-s::ListSignals* Name : %-s Title : %-s \n",ClassName(),GetName(),GetTitle());
3875 if (fTscmode!=2)
3876 {
3877 cout << " Timestamp of the measurement stored at index=" << j;
3878 }
3879 else
3880 {
3881 cout << " *Scrambled* timestamp of the measurement stored at index=" << j;
3882 }
3883 cout << " (Lab time offset w.r.t. UT : "; PrintTime(fToffset,12); cout << ")" << endl;
3884 tx->Date(dform,fToffset);
3885 tx->Date(4);
3886 cout << " Corresponding location of this measurement" << endl;
3887 cout << " "; PrintSignal(frame,mode,tx,ndig,j,emode,1); cout << endl;
3888 iprint=1;
3889 }
3890
3891 TObjArray* arr=0;
3892 Int_t nstored=0;
3893 Int_t jlist=0;
3894 Int_t test=type;
3895 while (test<2)
3896 {
3897 if (test==0)
3898 {
3899 type=0;
3900 arr=fRefs;
3901 test=999;
3902 }
3903 if (test==1)
3904 {
3905 type=1;
3906 arr=fSigs;
3907 test=999;
3908 }
3909 if (test<0)
3910 {
3911 type=0;
3912 arr=fRefs;
3913 test=1;
3914 }
3915
3916 if (!arr) continue;
3917
3918 nstored=arr->GetEntries();
3919 jlist=0;
3920 TString namex="";
3921 for (Int_t i=1; i<=arr->GetSize(); i++)
3922 {
3923 sx=GetSignal(i,type);
3924 if (!sx) continue;
3925
3926 jlist++;
3927 if (nmax>=0 && jlist>nmax) break;
3928
3929 // Check for the name pattern
3930 namex=sx->GetName();
3931 if (name!="*" && !namex.Contains(name)) continue;
3932
3933 if (!iprint)
3934 {
3935 printf(" *%-s::ListSignals* Name : %-s Title : %-s \n",ClassName(),GetName(),GetTitle());
3936 if (j==0) tx=ts;
3937 if (tx)
3938 {
3939 cout << " User provided timestamp (Lab time offset w.r.t. UT : "; PrintTime(fToffset,12); cout << ")";
3940 cout << endl;
3941 tx->Date(dform,fToffset);
3942 tx->Date(4);
3943 }
3944 else
3945 {
3946 tx=(NcTimestamp*)this;
3947 if (j>=0)
3948 {
3949 cout << " Current timestamp of the laboratory (Lab time offset w.r.t. UT : "; PrintTime(fToffset,12); cout << ")";
3950 cout << endl;
3951 tx->Date(dform,fToffset);
3952 tx->Date(4);
3953 }
3954 }
3955 iprint=1;
3956 }
3957 if (iprint==1)
3958 {
3959 if (nmax<0 || nmax>=nstored)
3960 {
3961 if (!type)
3962 {
3963 if (j>=0)
3964 {
3965 cout << " === All stored reference signals according to the above timestamp ===" << endl;
3966 }
3967 else
3968 {
3969 cout << " === All stored reference signals according to their actual recorded timestamp ===" << endl;
3970 }
3971 }
3972 else
3973 {
3974 if (fTscmode!=2)
3975 {
3976 cout << " === All stored measurements according to their actual observation timestamp ===" << endl;
3977 }
3978 else
3979 {
3980 cout << " === All stored measurements according to their *scrambled* observation timestamp ===" << endl;
3981 cout << " === Time scrambling was performed by adding dt from the interval [dtmin,dtmax] to their actual timestamp" << endl;
3982 cout << " === dtmin : " << fTscmin << " dtmax : " << fTscmax << " sec.";
3983 if (fTscfunc)
3984 {
3985 cout << " Randomising TF1 function " << fTscfunc->GetName() << " was used." << endl;
3986 }
3987 else
3988 {
3989 cout << " Uniform randomisation was used." << endl;
3990 }
3991 }
3992 }
3993 }
3994 else
3995 {
3996 if (!type)
3997 {
3998 if (j>=0)
3999 {
4000 cout << " === The first " << nmax << " stored reference signals according to the above timestamp ===" << endl;
4001 }
4002 else
4003 {
4004 cout << " === The first " << nmax << " stored reference signals according to their actual recorded timestamp ===" << endl;
4005 }
4006 }
4007 else
4008 {
4009 if (fTscmode!=2)
4010 {
4011 cout << " === The first " << nmax << " stored measurements according to their actual observation timestamp ===" << endl;
4012 }
4013 else
4014 {
4015 cout << " === The first " << nmax << " stored measurements according to their *scrambled* observation timestamp ===" << endl;
4016 cout << " === Time scrambling was performed by adding dt from the interval [dtmin,dtmax] to their actual timestamp" << endl;
4017 cout << " === dtmin : " << fTscmin << " dtmax : " << fTscmax << " sec.";
4018 if (fTscfunc)
4019 {
4020 cout << " Randomising TF1 function " << fTscfunc->GetName() << " was used." << endl;
4021 }
4022 else
4023 {
4024 cout << " Uniform randomisation was used." << endl;
4025 }
4026 }
4027 }
4028 }
4029 iprint=2;
4030 }
4031 if (type==1 || (!type && j<0)) tx=0;
4032 printf(" Index : %*d ",width,i); PrintSignal(frame,mode,tx,ndig,i,emode,type,kTRUE); printf("\n");
4033 }
4034 iprint=1;
4035 }
4036}
4037
4039{
4064
4065 // Convert back to J2000 values
4066 Nc3Vector r0;
4067 SetPmatrix(ts1);
4068 r0=r.GetUnprimed(&fP);
4069
4070 // Precess to the specified timestamp
4071 if (!ts2) ts2=(NcTimestamp*)this;
4072 SetPmatrix(ts2);
4073 r=r0.GetPrimed(&fP);
4074}
4075
4077{
4097
4098 // Nutation correction for the specified timestamp
4099 if (!ts) ts=(NcTimestamp*)this;
4100 SetNmatrix(ts);
4101 r=r.GetPrimed(&fN);
4102}
4103
4105{
4114
4115 Double_t pi=acos(-1.);
4116
4117 // Parameters in mas
4118 Double_t a=-14.6;
4119 Double_t x=-16.6170;
4120 Double_t e=-6.8192;
4121
4122 // Convert to radians
4123 a*=pi/(180.*3600.*1000.);
4124 x*=pi/(180.*3600.*1000.);
4125 e*=pi/(180.*3600.*1000.);
4126
4127 Double_t mat[9];
4128 mat[0]=1.-0.5*(a*a+x*x);
4129 mat[1]=a;
4130 mat[2]=-x;
4131 mat[3]=-a-e*x;
4132 mat[4]=1.-0.5*(a*a+e*e);
4133 mat[5]=-e;
4134 mat[6]=x-e*a;
4135 mat[7]=e+x*a;
4136 mat[8]=1.-0.5*(e*e+x*x);
4137
4138 fB.SetMatrix(mat);
4139 fBias=1;
4140}
4141
4143{
4153
4154 Double_t mat[9]={0,0,0,0,0,0,0,0,0};
4155 if (!ts)
4156 {
4157 fP.SetMatrix(mat);
4158 return;
4159 }
4160
4161 Double_t pi=acos(-1.);
4162
4163 Double_t t=(ts->GetJD()-2451545.0)/36525.; // Julian centuries since J2000.0
4164
4165 // Parameters for the precession matrix in arcseconds
4166 Double_t eps0=84381.406; // Mean ecliptic obliquity at J2000.0
4167 Double_t psi=5038.481507*t-1.0790069*pow(t,2)-0.00114045*pow(t,3)+0.000132851*pow(t,4)
4168 -0.0000000951*pow(t,4);
4169 Double_t om=eps0-0.025754*t+0.0512623*pow(t,2)-0.00772503*pow(t,3)-0.000000467*pow(t,4)
4170 +0.0000003337*pow(t,5);
4171 Double_t chi=10.556403*t-2.3814292*pow(t,2)-0.00121197*pow(t,3)+0.000170663*pow(t,4)
4172 -0.0000000560*pow(t,5);
4173
4174 // Convert to radians
4175 eps0*=pi/(180.*3600.);
4176 psi*=pi/(180.*3600.);
4177 om*=pi/(180.*3600.);
4178 chi*=pi/(180.*3600.);
4179
4180 Double_t s1=sin(eps0);
4181 Double_t s2=sin(-psi);
4182 Double_t s3=sin(-om);
4183 Double_t s4=sin(chi);
4184 Double_t c1=cos(eps0);
4185 Double_t c2=cos(-psi);
4186 Double_t c3=cos(-om);
4187 Double_t c4=cos(chi);
4188
4189 mat[0]=c4*c2-s2*s4*c3;
4190 mat[1]=c4*s2*c1+s4*c3*c2*c1-s1*s4*s3;
4191 mat[2]=c4*s2*s1+s4*c3*c2*s1+c1*s4*s3;
4192 mat[3]=-s4*c2-s2*c4*c3;
4193 mat[4]=-s4*s2*c1+c4*c3*c2*c1-s1*c4*s3;
4194 mat[5]=-s4*s2*s1+c4*c3*c2*s1+c1*c4*s3;
4195 mat[6]=s2*s3;
4196 mat[7]=-s3*c2*c1-s1*c3;
4197 mat[8]=-s3*c2*s1+c3*c1;
4198
4199 fP.SetMatrix(mat);
4200}
4201
4203{
4212
4213 Double_t mat[9]={0,0,0,0,0,0,0,0,0};
4214 if (!ts)
4215 {
4216 fN.SetMatrix(mat);
4217 return;
4218 }
4219
4220 Double_t pi=acos(-1.);
4221
4222 Double_t dpsi,deps,eps;
4223 ts->Almanac(&dpsi,&deps,&eps);
4224
4225 // Convert to radians
4226 dpsi*=pi/(180.*3600.);
4227 deps*=pi/(180.*3600.);
4228 eps*=pi/(180.*3600.);
4229
4230 Double_t s1=sin(eps);
4231 Double_t s2=sin(-dpsi);
4232 Double_t s3=sin(-(eps+deps));
4233 Double_t c1=cos(eps);
4234 Double_t c2=cos(-dpsi);
4235 Double_t c3=cos(-(eps+deps));
4236
4237 mat[0]=c2;
4238 mat[1]=s2*c1;
4239 mat[2]=s2*s1;
4240 mat[3]=-s2*c3;
4241 mat[4]=c3*c2*c1-s1*s3;
4242 mat[5]=c3*c2*s1+c1*s3;
4243 mat[6]=s2*s3;
4244 mat[7]=-s3*c2*c1-s1*c3;
4245 mat[8]=-s3*c2*s1+c3*c1;
4246
4247 fN.SetMatrix(mat);
4248}
4249
4250void NcAstrolab::SetGmatrix(TString mode)
4251{
4264
4265 Nc3Vector x; // The Galactic x-axis in the equatorial frame
4266 Nc3Vector y; // The Galactic y-axis in the equatorial frame
4267 Nc3Vector z; // The Galactic z-axis in the equatorial frame
4268
4269 Double_t a,d;
4270 Double_t vec[3]={1,0,0};
4271
4272 fGal=1; // Set flag to indicate B1950 matrix values
4273
4274 // B1950 equatorial coordinates of the North Galactic Pole (NGP)
4275 a=124900.;
4276 d=272400.;
4277 a=ConvertAngle(a,"hms","deg");
4278 d=ConvertAngle(d,"dms","deg");
4279 vec[1]=90.-d;
4280 vec[2]=a;
4281 z.SetVector(vec,"sph","deg");
4282
4283 // B1950 equatorial coordinates of the Galactic l=b=0 point
4284 a=174224.;
4285 d=-285500.;
4286 a=ConvertAngle(a,"hms","deg");
4287 d=ConvertAngle(d,"dms","deg");
4288 vec[1]=90.-d;
4289 vec[2]=a;
4290 x.SetVector(vec,"sph","deg");
4291
4292 // Precess to the corresponding J2000 values if requested
4293 if (mode=="J")
4294 {
4295 fGal=2; // Set flag to indicate J2000 matrix values
4296 NcTimestamp t1;
4297 t1.SetEpoch(1950,"B");
4298 NcTimestamp t2;
4299 t2.SetEpoch(2000,"J");
4300 Precess(z,&t1,&t2);
4301 Precess(x,&t1,&t2);
4302 }
4303
4304 // The Galactic y-axis is determined for the right handed frame
4305 y=z.Cross(x);
4306
4307 fG.SetAngles(x.GetX(2,"sph","deg"),x.GetX(3,"sph","deg"),
4308 y.GetX(2,"sph","deg"),y.GetX(3,"sph","deg"),
4309 z.GetX(2,"sph","deg"),z.GetX(3,"sph","deg"));
4310}
4311
4313{
4322
4323 Double_t dpsi,deps,eps;
4324 ts->Almanac(&dpsi,&deps,&eps);
4325
4326 // Convert to degrees
4327 eps/=3600.;
4328
4329 // Positions of the ecliptic axes w.r.t. the equatorial ones
4330 // at the moment of the specified timestamp
4331 Double_t theta1=90; // Ecliptic x-axis
4332 Double_t phi1=0;
4333 Double_t theta2=90.-eps; //Ecliptic y-axis
4334 Double_t phi2=90;
4335 Double_t theta3=eps; // Ecliptic z-axis
4336 Double_t phi3=270;
4337
4338 fE.SetAngles(theta1,phi1,theta2,phi2,theta3,phi3);
4339}
4340
4342{
4354
4355 Nc3Vector x; // The (South pointing) horizontal x-axis in the equatorial frame
4356 Nc3Vector y; // The (East pointing) horizontal y-axis in the equatorial frame
4357 Nc3Vector z; // The (Zenith pointing) horizontal z-axis in the equatorial frame
4358
4359 Double_t l,b;
4360 GetLabPosition(l,b,"deg");
4361
4362 Double_t a;
4363 Double_t vec[3]={1,0,0};
4364
4365 // Equatorial coordinates of the horizontal z-axis
4366 // at the moment of the specified timestamp
4367 a=ts->GetLAST(fToffset);
4368 a*=15.; // Convert fractional hours to degrees
4369 vec[1]=90.-b;
4370 vec[2]=a;
4371 z.SetVector(vec,"sph","deg");
4372
4373 // Equatorial coordinates of the horizontal x-axis
4374 // at the moment of the specified timestamp
4375 vec[1]=180.-b;
4376 vec[2]=a;
4377 x.SetVector(vec,"sph","deg");
4378
4379 // The horizontal y-axis is determined for the right handed frame
4380 y=z.Cross(x);
4381
4382 fH.SetAngles(x.GetX(2,"sph","deg"),x.GetX(3,"sph","deg"),
4383 y.GetX(2,"sph","deg"),y.GetX(3,"sph","deg"),
4384 z.GetX(2,"sph","deg"),z.GetX(3,"sph","deg"));
4385}
4386
4387void NcAstrolab::SetLocalFrame(Double_t t1,Double_t p1,Double_t t2,Double_t p2,Double_t t3,Double_t p3)
4388{
4417
4418 // Set the matrix for the conversion of our reference frame coordinates
4419 // into the local-frame ones.
4420
4421 fL.SetAngles(t1,p1,t2,p2,t3,p3);
4422
4423 // Store the local user frame axes orientations w.r.t. the standard local Horizon (zen,azi) frame
4424 fAxes[0]=t1;
4425 fAxes[1]=p1;
4426 fAxes[2]=t2;
4427 fAxes[3]=p2;
4428 fAxes[4]=t3;
4429 fAxes[5]=p3;
4430}
4431
4433{
4443
4444 arr[0]=fAxes[0];
4445 arr[1]=fAxes[1];
4446 arr[2]=fAxes[2];
4447 arr[3]=fAxes[3];
4448 arr[4]=fAxes[4];
4449 arr[5]=fAxes[5];
4450}
4451
4452Double_t NcAstrolab::ConvertAngle(Double_t a,TString in,TString out) const
4453{
4474
4475 if (in==out) return a;
4476
4477 // Convert input to its absolute value in (fractional) degrees.
4478 Double_t pi=acos(-1.);
4479 Double_t epsilon=1.e-12; // Accuracy in (arc)seconds
4480 Int_t word=0,ddd=0,hh=0,mm=0,ss=0;
4481 Double_t s=0;
4482
4483 Double_t b=fabs(a);
4484
4485 if (in=="rad") b*=180./pi;
4486
4487 if (in=="hrs") b*=15.;
4488
4489 if (in=="dms")
4490 {
4491 word=Int_t(b);
4492 ddd=word/10000;
4493 word=word%10000;
4494 mm=word/100;
4495 ss=word%100;
4496 s=b-Double_t(ddd*10000+mm*100+ss);
4497 b=Double_t(ddd)+Double_t(mm)/60.+(Double_t(ss)+s)/3600.;
4498 }
4499
4500 if (in=="hms")
4501 {
4502 word=Int_t(b);
4503 hh=word/10000;
4504 word=word%10000;
4505 mm=word/100;
4506 ss=word%100;
4507 s=b-Double_t(hh*10000+mm*100+ss);
4508 b=15.*(Double_t(hh)+Double_t(mm)/60.+(Double_t(ss)+s)/3600.);
4509 }
4510
4511 while (b>360)
4512 {
4513 b-=360.;
4514 }
4515
4516 if (out=="rad") b*=pi/180.;
4517
4518 if (out=="hrs") b/=15.;
4519
4520 if (out=="dms")
4521 {
4522 ddd=Int_t(b);
4523 b=b-Double_t(ddd);
4524 b*=60.;
4525 mm=Int_t(b);
4526 b=b-Double_t(mm);
4527 b*=60.;
4528 ss=Int_t(b);
4529 s=b-Double_t(ss);
4530 if (s>(1.-epsilon))
4531 {
4532 s=0.;
4533 ss++;
4534 }
4535 while (ss>=60)
4536 {
4537 ss-=60;
4538 mm++;
4539 }
4540 while (mm>=60)
4541 {
4542 mm-=60;
4543 ddd++;
4544 }
4545 while (ddd>=360)
4546 {
4547 ddd-=360;
4548 }
4549 b=Double_t(10000*ddd+100*mm+ss)+s;
4550 }
4551
4552 if (out=="hms")
4553 {
4554 b/=15.;
4555 hh=Int_t(b);
4556 b=b-Double_t(hh);
4557 b*=60.;
4558 mm=Int_t(b);
4559 b=b-Double_t(mm);
4560 b*=60.;
4561 ss=Int_t(b);
4562 s=b-Double_t(ss);
4563 if (s>(1.-epsilon))
4564 {
4565 s=0.;
4566 ss++;
4567 }
4568 while (ss>=60)
4569 {
4570 ss-=60;
4571 mm++;
4572 }
4573 while (mm>=60)
4574 {
4575 mm-=60;
4576 hh++;
4577 }
4578 while (hh>=24)
4579 {
4580 hh-=24;
4581 }
4582 b=Double_t(10000*hh+100*mm+ss)+s;
4583 }
4584
4585 if (a<0) b=-b;
4586
4587 return b;
4588}
4589
4590Double_t NcAstrolab::GetSolidAngle(Double_t thetamin,Double_t thetamax,TString tu,Double_t phimin,Double_t phimax,TString pu) const
4591{
4606
4607 Double_t omega=0;
4608
4609 Double_t th1=ConvertAngle(thetamin,tu,"rad");
4610 Double_t th2=ConvertAngle(thetamax,tu,"rad");
4611 Double_t ph1=ConvertAngle(phimin,pu,"rad");
4612 Double_t ph2=ConvertAngle(phimax,pu,"rad");
4613
4614 omega=(ph2-ph1)*(cos(th1)-cos(th2));
4615 if (omega<0) omega=-omega;
4616
4617 return omega;
4618}
4619
4620Double_t NcAstrolab::GetHourAngle(TString mode,NcTimestamp* ts,Int_t jref,Int_t type)
4621{
4655
4656 if (!ts) ts=(NcTimestamp*)this;
4657
4658 // Get corrected right ascension and declination for the specified timestamp.
4659 Double_t d,a,b;
4660 if (mode=="M" || mode=="m") GetSignal(d,a,"deg",b,"deg","equ",ts,jref,"M",type);
4661 if (mode=="A" || mode=="a") GetSignal(d,a,"deg",b,"deg","equ",ts,jref,"T",type);
4662
4663 a/=15.; // Convert a to fractional hours
4664 Double_t ha=0;
4665 if (mode=="M" || mode=="m") ha=ts->GetLMST(fToffset)-a;
4666 if (mode=="A" || mode=="a") ha=ts->GetLAST(fToffset)-a;
4667 ha*=15.; // Convert to (fractional) degrees
4668
4669 // Project to the interval [-180,180]
4670 while (ha<-180)
4671 {
4672 ha+=360.;
4673 }
4674 while (ha>180)
4675 {
4676 ha-=360.;
4677 }
4678
4679 return ha;
4680}
4681
4682void NcAstrolab::SetLT(Int_t y,Int_t m,Int_t d,Int_t hh,Int_t mm,Int_t ss,Int_t ns,Int_t ps)
4683{
4705
4706 SetLT(fToffset,y,m,d,hh,mm,ss,ns,ps);
4707}
4708
4709void NcAstrolab::SetLT(Int_t y,Int_t m,Int_t d,Int_t hh,Int_t mm,Double_t s)
4710{
4731
4732 SetLT(fToffset,y,m,d,hh,mm,s);
4733}
4734
4735void NcAstrolab::SetLT(Int_t y,Int_t m,Int_t d,TString time)
4736{
4755
4756 SetLT(fToffset,y,m,d,time);
4757}
4758
4759void NcAstrolab::SetLT(TString date,TString time,Int_t mode)
4760{
4781
4782 SetLT(fToffset,date,time,mode);
4783}
4784
4785void NcAstrolab::SetLT(Int_t y,Int_t d,Int_t s,Int_t ns,Int_t ps)
4786{
4811
4812 SetLT(fToffset,y,d,s,ns,ps);
4813}
4814
4815Double_t NcAstrolab::GetDifference(Int_t j,TString au,Double_t& dt,TString tu,Int_t mode,Int_t* ia,Int_t* it)
4816{
4862
4863 Double_t da=999;
4864 dt=1.e30;
4865
4866 if (ia) *ia=0;
4867 if (it) *it=0;
4868
4869 if (j<0) return da;
4870
4871 NcDevice matches;
4872 Int_t nhits=0;
4873 NcSignal* sx=0;
4874 if (j) // Space and time difference w.r.t. a specific reference signal
4875 {
4876 MatchSignals(matches,da,au,dt,tu,mode,j,j,0,1,1,1);
4877 nhits=matches.GetNhits();
4878 if (nhits)
4879 {
4880 da=matches.GetSignal(1);
4881 dt=matches.GetSignal(2);
4882 if (ia) *ia=j;
4883 if (it) *it=j;
4884 }
4885 }
4886 else // Minimal space and time difference encountered over all reference signals
4887 {
4888 MatchSignals(matches,da,au,dt,tu,mode,1,0,0,1,1,1);
4889 nhits=matches.GetNhits();
4890 if (nhits)
4891 {
4892 da=matches.GetSignal(1);
4893 dt=matches.GetSignal(2);
4894 if (ia)
4895 {
4896 Int_t ipsi=matches.GetSignal("ipsi");
4897 sx=matches.GetHit(ipsi);
4898 if (sx) *ia=sx->GetSignal("index1");
4899 }
4900 if (it)
4901 {
4902 Int_t idt=matches.GetSignal("idt");
4903 sx=matches.GetHit(idt);
4904 if (sx) *it=sx->GetSignal("index1");
4905 }
4906 }
4907 }
4908 return da;
4909}
4910
4911Double_t NcAstrolab::GetSeparation(TString name1,TString name2,TString au,Double_t* dt,TString tu,Int_t mode,Double_t* diftheta,Double_t* difphi)
4912{
4959
4960 // Obtain the storage indices for the requested signals
4961 Int_t i=GetSignalIndex(name1,1); // Search for "name1" among the measurement signals
4962 Int_t j=GetSignalIndex(name2,1); // Search for "name2" among the measurement signals
4963
4964 if (i>0) // Set to negative value to indicate measurement entry
4965 {
4966 i=-i;
4967 }
4968 else // Search for "name1" among the reference signals
4969 {
4970 // In case a Solar system body was specified, store c.q. update it as a reference object.
4971 SetSolarSystem(name1,0,0);
4972 i=GetSignalIndex(name1,0);
4973 if (i<0) i=0;
4974 }
4975
4976 if (j>0) // Set to negative value to indicate measurement entry
4977 {
4978 j=-j;
4979 }
4980 else // Search for "name2" among the reference signals
4981 {
4982 // In case a Solar system body was specified, store c.q. update it as a reference object.
4983 SetSolarSystem(name2,0,0);
4984 j=GetSignalIndex(name2,0);
4985 if (j<0) j=0;
4986 }
4987
4988 // Retrieve the requested data via the internal GetSeparation() memberfunction
4989 Double_t dtx;
4990 Double_t da=GetSeparation(i,j,au,dtx,tu,mode,0,diftheta,difphi);
4991
4992Double_t dthetax,dphix;
4993da=GetSeparation(i,j,au,dtx,tu,mode,0,&dthetax,&dphix);
4994printf(" i=%-i j=%-i da=%-g dt=%-g %-s dtheta=%-g dphi=%-g %-s \n",i,j,da,dtx,tu.Data(),dthetax,dphix,au.Data());
4995
4996 if (dt) *dt=dtx;
4997 return da;
4998}
4999
5000Double_t NcAstrolab::GetSeparation(Int_t i,Int_t j,TString au,Double_t& dt,TString tu,Int_t mode,Int_t bkgpatch,Double_t* diftheta,Double_t* difphi)
5001{
5049
5050 Double_t dang=-999;
5051 dt=1.e30;
5052 if (diftheta) *diftheta=-999;
5053 if (difphi) *difphi=-999;
5054
5055 if (!i || !j) return dang;
5056 if ((i>0 || j>0) && !fRefs) return dang;
5057 if ((i<0 || j<0) && !fSigs) return dang;
5058
5059 // If needed, initialise the randomiser with a "date/time driven" seed
5060 // using the timestamp of the moment of this invokation of the member function.
5061 // This will ensure different random sequences if the user repeats analyses
5062 // with identical measurements and reference signals without explicit initialisation
5063 // of the randomiser by the user at the start of the analysis.
5064 if (!fRan && (fRscmode>0 || fTscmode>0)) fRan=new NcRandom(-1);
5065
5066 Int_t itype=0;
5067 if (i<0)
5068 {
5069 itype=1;
5070 i=abs(i);
5071 }
5072
5073 Int_t jtype=0;
5074 if (j<0)
5075 {
5076 jtype=1;
5077 j=abs(j);
5078 }
5079
5080 Nc3Vector ri; // Position of the i-th signal
5081 Nc3Vector rj; // Position of the j-th signal
5082 NcSignal* si=0; // Link to the stored i-th signal
5083 NcSignal* sj=0; // Link to the stored j-th signal
5084 NcTimestamp* ti=0; // Link to the timestamp of the i-th signal
5085 NcTimestamp* tj=0; // Link to the timestamp of the j-th signal
5086
5087 si=GetSignal(i,itype);
5088 sj=GetSignal(j,jtype);
5089 if (!si || !sj) return dang;
5090
5091 ti=si->GetTimestamp();
5092 tj=sj->GetTimestamp();
5093 if (!ti || !tj) return dang;
5094
5095 Int_t reftype=0;
5096 Int_t evttype=0;
5097 Int_t idxref=0;
5098 Int_t idxevt=0;
5099 NcSignal* sxref=0; // Link to the stored reference signal
5100 NcTimestamp* txref=0; // Link to the timestamp of the reference signal
5101 NcTimestamp* txevt=0; // Link to the timestamp of the measurement signal
5102 Nc3Vector rxref; // Position of the reference signal
5103 Nc3Vector rxevt; // Position of the measurement signal
5104
5105 if (itype==jtype) // Self correlations
5106 {
5107 reftype=itype;
5108 idxref=i;
5109 sxref=si;
5110 txref=ti;
5111 evttype=jtype;
5112 idxevt=j;
5113 txevt=tj;
5114 }
5115 else // Correlations between sources and measurements
5116 {
5117 if (itype)
5118 {
5119 evttype=itype;
5120 idxevt=i;
5121 txevt=ti;
5122 reftype=jtype;
5123 idxref=j;
5124 sxref=sj;
5125 txref=tj;
5126 }
5127 else
5128 {
5129 reftype=itype;
5130 idxref=i;
5131 sxref=si;
5132 txref=ti;
5133 evttype=jtype;
5134 idxevt=j;
5135 txevt=tj;
5136 }
5137 }
5138
5139 // Update the location and timestamp in case of a Solar system reference object
5140 TString name=sxref->GetName();
5141 if (SetSolarSystem(name,txevt,reftype)) txref=sxref->GetTimestamp();
5142
5143 // Local variables to act on requested scrambling
5144 Int_t Tscmode=fTscmode;
5145 Int_t Rscmode=fRscmode;
5146
5147 // Create scrambled background patch data even when also the on-source data are scrambled
5148 if (bkgpatch)
5149 {
5150 Tscmode=-abs(fTscmode);
5151 Rscmode=-abs(fRscmode);
5152 }
5153
5154 // Apply time scrambling of the date/time of the observation if requested
5155 NcTimestamp txtmp(*txevt);
5156 Double_t trndm=0;
5157 if (Tscmode==1 || Tscmode==3 || (Tscmode<0 && bkgpatch))
5158 {
5159 if (!fTscfunc)
5160 {
5161 trndm=fRan->Uniform(fTscmin,fTscmax);
5162 }
5163 else
5164 {
5165 trndm=fTscfunc->GetRandom(fTscmin,fTscmax);
5166 }
5167 // Creating a fake scrambled timestamp
5168 if (Tscmode==3 || (abs(Tscmode)>1 && bkgpatch)) txtmp.AddSec(trndm);
5169 }
5170
5171 // Obtain the (scrambled) time difference
5172 if (Tscmode==1 || (Tscmode==-1 && bkgpatch)) // Only provide a random time difference
5173 {
5174 if (tu=="d")
5175 {
5176 trndm/=double(24*3600);
5177 }
5178 if (tu=="ns")
5179 {
5180 trndm*=1.e9;
5181 trndm*=1.e9;
5182 }
5183 if (tu=="ps")
5184 {
5185 trndm*=1.e12;
5186 trndm*=1.e12;
5187 }
5188 dt=trndm;
5189 }
5190 else // Determine the time difference w.r.t. the fake timestamp of the measurement
5191 {
5192 dt=txref->GetDifference(&txtmp,tu,mode);
5193 }
5194
5195 // Update the location of Solar system objects if needed
5196 name=sxref->GetName();
5197 SetSolarSystem(name,&txtmp,reftype);
5198
5199 // Get the original measurement position and (time modified) reference position in local coordinates
5200 GetSignal(rxevt,"loc","T",txevt,idxevt,evttype);
5201 GetSignal(rxref,"loc","T",&txtmp,idxref,reftype);
5202
5203 // Apply position scrambling of the measurement if requested
5204 Double_t pi=acos(-1.);
5205 Float_t cosmin=0;
5206 Float_t cosmax=0;
5207 Double_t cosang=0;
5208 Double_t vec[3];
5209 Double_t dd=0;
5210 Double_t dtheta=0;
5211 Double_t dphi=0;
5212
5213 if (Rscmode==1 || (Rscmode==-1 && bkgpatch)) // Only provide a random angular separation
5214 {
5215 if (!fDscfunc)
5216 {
5217 cosmin=cos(fDscmin*pi/180.);
5218 cosmax=cos(fDscmax*pi/180.);
5219 if (cosmin>cosmax)
5220 {
5221 Float_t temp=cosmin;
5222 cosmin=cosmax;
5223 cosmax=temp;
5224 }
5225 cosang=fRan->Uniform(cosmin,cosmax);
5226 dang=acos(cosang);
5227 if (au=="deg") dang*=180./pi;
5228 }
5229 else
5230 {
5231 dang=fDscfunc->GetRandom(fDscmin,fDscmax);
5232 if (au=="rad") dang*=pi/180.;
5233 }
5234 }
5235 else // Create a fake local position for the measurement
5236 {
5237 if (Rscmode==3 || (abs(Rscmode)>1 && bkgpatch))
5238 {
5239 rxevt.GetVector(vec,"sph","deg");
5240
5241 // Allow specific offset studies
5242 if (fDscmin==fDscmax) dd=fDscmin;
5243 if (fThetascmin==fThetascmax) dtheta=fThetascmin;
5244 if (fPhiscmin==fPhiscmax) dphi=fPhiscmin;
5245
5246 // Go for randomly scrambled values
5247 if (fDscfunc)
5248 {
5249 if (fDscmax>fDscmin)
5250 {
5251 dd=fDscfunc->GetRandom(fDscmin,fDscmax);
5252 }
5253 }
5254 else
5255 {
5256 if (fDscmax>fDscmin) dd=fRan->Uniform(fDscmin,fDscmax);
5257 }
5258
5259 if (fThetascfunc)
5260 {
5262 {
5263 dtheta=fThetascfunc->GetRandom(fThetascmin,fThetascmax);
5264 }
5265 }
5266 else if (fThetascmax>fThetascmin)
5267 {
5268 cosmin=cos(fThetascmin*pi/180.);
5269 cosmax=cos(fThetascmax*pi/180.);
5270 if (cosmin>cosmax)
5271 {
5272 Float_t temp=cosmin;
5273 cosmin=cosmax;
5274 cosmax=temp;
5275 }
5276 cosang=fRan->Uniform(cosmin,cosmax);
5277 dtheta=acos(cosang)*180./pi;
5278 }
5279
5280 if (fPhiscfunc)
5281 {
5282 if (fPhiscmax>fPhiscmin)
5283 {
5284 dphi=fPhiscfunc->GetRandom(fPhiscmin,fPhiscmax);
5285 }
5286 }
5287 else
5288 {
5289 if (fPhiscmax>fPhiscmin) dphi=fRan->Uniform(fPhiscmin,fPhiscmax);
5290 }
5291
5292 vec[0]+=dd;
5293 if (vec[0]<=0) vec[0]=1e-20; // Keep a physical situation
5294 vec[1]+=dtheta;
5295 vec[2]+=dphi;
5296 rxevt.SetVector(vec,"sph","deg");
5297 }
5298
5299 dang=rxref.GetOpeningAngle(rxevt,au);
5300 }
5301
5302 // Determine the difference in local theta and phi
5303 Double_t refvec[3];
5304 rxevt.GetVector(vec,"sph",au);
5305 rxref.GetVector(refvec,"sph",au);
5306 dtheta=vec[1]-refvec[1];
5307 dphi=vec[2]-refvec[2];
5308 if (diftheta) *diftheta=dtheta;
5309 if (difphi) *difphi=dphi;
5310
5311 return dang;
5312}
5313
5314Double_t NcAstrolab::GetDifference(TString name,TString au,Double_t& dt,TString tu,Int_t mode)
5315{
5350
5351 Double_t dang=999;
5352 dt=1.e30;
5353
5354 Int_t j=GetSignalIndex(name);
5355
5356 if (j==-1) // Set and store info for the requested Solar system object if not already stored
5357 {
5358 SetSolarSystem(name,0);
5359 j=GetSignalIndex(name);
5360 }
5361
5362 if (j>0) dang=GetDifference(j,au,dt,tu,mode);
5363 return dang;
5364}
5365
5366TArrayI* NcAstrolab::MatchRefSignal(Double_t da,TString au,Double_t dt,TString tu,Int_t mode)
5367{
5396
5397 if (!fSigs || !fRefs) return 0;
5398
5399 NcDevice matches;
5400 MatchSignals(matches,da,au,dt,tu,mode,1,0,0,1,1,1); // Perform the obsolete MatchRefSignal() action
5401
5402 Int_t nhits=matches.GetNhits();
5403 if (!nhits) return 0;
5404
5405 if (fIndices) delete fIndices;
5406 fIndices=new TArrayI(nhits);
5407
5408 Int_t index=0;
5409 NcSignal* sx=0;
5410 Int_t jfill=0;
5411 for (Int_t i=1; i<=nhits; i++)
5412 {
5413 sx=matches.GetHit(i);
5414
5415 if(!sx) continue;
5416
5417 index=sx->GetSignal("index1");
5418 fIndices->AddAt(index,jfill);
5419 jfill++;
5420 }
5421
5422 fIndices->Set(jfill);
5423
5424 if (!jfill) return 0; // No match found
5425
5426 return fIndices;
5427}
5428
5429void NcAstrolab::MatchSignals(NcDevice& matches,Double_t da,TString au,Double_t dt,TString tu,Int_t mode,Int_t i1,Int_t i2,Int_t itype,Int_t j1,Int_t j2,Int_t jtype)
5430{
5542
5543 // Initialize the Device/Hit structure to contain the correlation info
5544 matches.Reset(1);
5545 matches.SetHitCopy(1);
5546
5547 TString name="Matches";
5548 TString title="Space and time matchings of NcAstrolab stored signals";
5549 matches.SetNameTitle(name.Data(),title.Data());
5550 TString tux=tu;
5551 if (tu=="d") tux="days";
5552 if (tu=="s") tux="sec";
5553 TString namedamin="psimin in ";
5554 namedamin+=au;
5555 TString namedtmin="dtmin in ";
5556 namedtmin+=tux;
5557 matches.AddNamedSlot(namedamin);
5558 matches.AddNamedSlot(namedtmin);
5559 matches.AddNamedSlot("ipsi");
5560 matches.AddNamedSlot("idt");
5561
5562 NcSignal data;
5563 TString nameda="psi in ";
5564 nameda+=au;
5565 TString namedt="t2-t1 in ";
5566 namedt+=tux;
5567 data.AddNamedSlot("type1");
5568 data.AddNamedSlot("index1");
5569 data.AddNamedSlot("type2");
5570 data.AddNamedSlot("index2");
5571 data.AddNamedSlot(nameda);
5572 data.AddNamedSlot(namedt);
5573
5574 if ((!itype || !jtype) && !fRefs)
5575 {
5576 printf(" *%-s::MatchSignals* Error: itype=%-i jtype=%-i but no reference signals are present. \n",ClassName(),itype,jtype);
5577 return;
5578 }
5579
5580 if ((itype || jtype) && !fSigs)
5581 {
5582 printf(" *%-s::MatchSignals* Error: itype=%-i jtype=%-i but no measurements are present. \n",ClassName(),itype,jtype);
5583 return;
5584 }
5585
5586 Int_t nrefs=0;
5587 if (fRefs) nrefs=fRefs->GetSize();
5588 Int_t nsigs=0;
5589 if (fSigs) nsigs=fSigs->GetSize();
5590
5591
5592 // Make input data consistent with conventions
5593 if (itype) itype=1;
5594 if (jtype) jtype=1;
5595 if (!itype)
5596 {
5597 if (i2<1 || i2>nrefs) i2=nrefs;
5598 }
5599 else
5600 {
5601 if (i2<1 || i2>nsigs) i2=nsigs;
5602 }
5603 if (!jtype)
5604 {
5605 if (j2<1 || j2>nrefs) j2=nrefs;
5606 }
5607 else
5608 {
5609 if (j2<1 || j2>nsigs) j2=nsigs;
5610 }
5611
5612 if (i1<1 || j1<1 || i1>i2 || j1>j2)
5613 {
5614 printf(" *%-s::MatchSignals* Inconsistent parameters: i1=%-i i2=%-i itype=%-i j1=%-i j2=%-i jtype=%-i. \n",ClassName(),i1,i2,itype,j1,j2,jtype);
5615 return;
5616 }
5617
5618 Double_t dang,dtime;
5619 Int_t ix=0;
5620 Int_t jx=0;
5621 NcSignal* sx=0;
5622 Int_t id=0;
5623 Double_t dangmin=0;
5624 Double_t dtmin=0;
5625 Int_t idamin=0;
5626 Int_t idtmin=0;
5627 Bool_t first=kTRUE;
5628 for (Int_t i=i1; i<=i2; i++)
5629 {
5630 ix=i;
5631 if (itype) ix=-i;
5632
5633 for (Int_t j=j1; j<=j2; j++)
5634 {
5635 // Skip matching a signal with itself
5636 if (itype==jtype && i==j) continue;
5637
5638 jx=j;
5639 if (jtype) jx=-j;
5640
5641 dang=GetSeparation(ix,jx,au,dtime,tu,mode,0);
5642
5643 if ((fabs(dang)<=da || da<0) && (fabs(dtime)<=dt || dt<0))
5644 {
5645 data.Reset();
5646 name="Object1=";
5647 sx=GetSignal(i,itype);
5648 if (!sx) continue;
5649 name+=sx->GetName();
5650 title="Object2=";
5651 sx=GetSignal(j,jtype);
5652 if (!sx) continue;
5653 title+=sx->GetName();
5654 id++;
5655 data.SetNameTitle(name.Data(),title.Data());
5656 data.SetUniqueID(id);
5657 data.SetSignal(itype,"type1");
5658 data.SetSignal(i,"index1");
5659 data.SetSignal(jtype,"type2");
5660 data.SetSignal(j,"index2");
5661 data.SetSignal(dtime,namedt);
5662 data.SetSignal(dang,nameda);
5663 matches.AddHit(data);
5664
5665 // Record the data for the minimal encountered opening angle
5666 if (first || fabs(dang)<dangmin)
5667 {
5668 dangmin=fabs(dang);
5669 idamin=id;
5670 }
5671
5672 // Record the data for the minimal encountered time difference
5673 if (first || fabs(dtime)<fabs(dtmin))
5674 {
5675 dtmin=dtime;
5676 idtmin=id;
5677 }
5678
5679 first=kFALSE;
5680 }
5681 }
5682 }
5683
5684 // Store the data for the minimal encountered opening angle and time difference
5685 matches.SetSignal(dangmin,namedamin);
5686 matches.SetSignal(dtmin,namedtmin);
5687 matches.SetSignal(idamin,"ipsi");
5688 matches.SetSignal(idtmin,"idt");
5689}
5690
5691void NcAstrolab::MatchSignals(NcDevice& matches,TString name,Double_t da,TString au,Double_t dt,TString tu,Int_t mode,Int_t itype,Int_t j1,Int_t j2,Int_t jtype)
5692{
5802
5803 Int_t i=GetSignalIndex(name,itype);
5804
5805 if (i==-1) // Add the info for the requested Solar system object if not already stored
5806 {
5807 SetSolarSystem(name,0,itype);
5808 i=GetSignalIndex(name,itype);
5809 if (i>0) fSolUpdate=1;
5810 }
5811
5812 if (i<1)
5813 {
5814 printf(" *%-s::MatchSignals* Object %-s not found for itype=%-i. \n",ClassName(),name.Data(),itype);
5815 }
5816 else
5817 {
5818 MatchSignals(matches,da,au,dt,tu,mode,i,i,itype,j1,j2,jtype);
5819 }
5820
5821 fSolUpdate=0;
5822}
5823
5824void NcAstrolab::SetTimeScramble(Int_t mode,Double_t tmin,Double_t tmax,TF1* frndm)
5825{
5895
5896 fTscmode=mode;
5897 fTscmin=tmin;
5898 fTscmax=tmax;
5899 if (fTscfunc)
5900 {
5901 delete fTscfunc;
5902 fTscfunc=0;
5903 }
5904 if (frndm)
5905 {
5906 fTscfunc=new TF1(*frndm);
5907 if (tmax>tmin) fTscfunc->SetRange(tmin,tmax);
5908 }
5909}
5910
5911Int_t NcAstrolab::GetTimeScramble(Double_t* tmin,Double_t* tmax,TF1* frndm)
5912{
5942
5943 if (tmin) *tmin=fTscmin;
5944 if (tmax) *tmax=fTscmax;
5945 if (frndm) *frndm=*fTscfunc;
5946
5947 return fTscmode;
5948}
5949
5950void NcAstrolab::SetPositionScramble(Int_t mode,Double_t dmin,Double_t dmax,TF1* df,Double_t thmin,Double_t thmax,TF1* thf,Double_t phimin,Double_t phimax,TF1* phif)
5951{
6029
6030 // Keep parameters within physical bounds for angular difference scrambling (mode=1)
6031 if (abs(mode)==1 && dmin<0) dmin=0;
6032 if (abs(mode)==1 && dmax>180) dmax=180;
6033
6034 // Check for specific requested offsets
6035 if (dmax<dmin) dmax=dmin;
6036 if (thmax<thmin) thmax=thmin;
6037 if (phimax<phimin) phimax=phimin;
6038
6039 fRscmode=mode;
6040 fDscmin=dmin;
6041 fDscmax=dmax;
6042 if (fDscfunc)
6043 {
6044 delete fDscfunc;
6045 fDscfunc=0;
6046 }
6047 if (df)
6048 {
6049 fDscfunc=new TF1(*df);
6050 if (dmax>dmin) fDscfunc->SetRange(dmin,dmax);
6051 }
6052 fThetascmin=thmin;
6053 fThetascmax=thmax;
6054 if (fThetascfunc)
6055 {
6056 delete fThetascfunc;
6057 fThetascfunc=0;
6058 }
6059 if (thf)
6060 {
6061 fThetascfunc=new TF1(*thf);
6062 if (thmax>thmin) fThetascfunc->SetRange(thmin,thmax);
6063 }
6064 fPhiscmin=phimin;
6065 fPhiscmax=phimax;
6066 if (fPhiscfunc)
6067 {
6068 delete fPhiscfunc;
6069 fPhiscfunc=0;
6070 }
6071 if (phif)
6072 {
6073 fPhiscfunc=new TF1(*phif);
6074 if (phimax>phimin) fPhiscfunc->SetRange(phimin,phimax);
6075 }
6076}
6077
6078Int_t NcAstrolab::GetPositionScramble(Double_t* dmin,Double_t* dmax,TF1* df,Double_t* thmin,Double_t* thmax,TF1* thf,Double_t* phimin,Double_t* phimax,TF1* phif)
6079{
6115
6116 if (dmin) *dmin=fDscmin;
6117 if (dmax) *dmax=fDscmax;
6118 if (df) *df=*fDscfunc;
6119 if (thmin) *thmin=fThetascmin;
6120 if (thmax) *thmax=fThetascmax;
6121 if (thf) *thf=*fThetascfunc;
6122 if (phimin) *phimin=fPhiscmin;
6123 if (phimax) *phimax=fPhiscmax;
6124 if (phif) *phif=*fPhiscfunc;
6125
6126 return fRscmode;
6127}
6128
6129void NcAstrolab::DisplaySignal(TString frame,TString mode,NcTimestamp* ts,Int_t j,TString proj,Int_t clr,TString name)
6130{
6229
6230 // Comply with the new (jref,type) convention for measurements and reference signals.
6231 Int_t jref=abs(j);
6232 Int_t type=0;
6233 if (j<=0) type=1;
6234 if (!j) jref=1;
6235
6236 NcSignal* sx=0;
6237
6238 if (!ts)
6239 {
6240 sx=GetSignal(jref,type);
6241 if (!sx) return;
6242 ts=sx->GetTimestamp();
6243 }
6244
6245 Nc3Vector r;
6246 sx=GetSignal(r,frame,mode,ts,jref,type);
6247
6248 if (!sx) return;
6249
6250 // Save name and timestamp to enable timestamp restoration for Solar system objects
6251 // after a Day View or Year View display
6252 TString namesave=sx->GetName();
6253 NcTimestamp tsave=(*ts);
6254
6255 // The generic input angles (in rad) for the projections
6256 Double_t theta=0;
6257 Double_t phi=0;
6258
6259 Double_t pi=acos(-1.);
6260
6261 if (frame=="equ" || frame=="gal" || frame=="icr" || frame=="ecl" || frame=="loc")
6262 {
6263 theta=(pi/2.)-r.GetX(2,"sph","rad");
6264 phi=r.GetX(3,"sph","rad");
6265 }
6266
6267 if (frame=="hor")
6268 {
6269 theta=(pi/2.)-r.GetX(2,"sph","rad");
6270 phi=pi-r.GetX(3,"sph","rad");
6271 }
6272
6273 // Automatic choice of central meridian if not selected by the user
6274 if (!fUsMeridian || abs(fUsMeridian)>1)
6275 {
6276 if (frame=="equ")
6277 {
6278 fMeridian=pi;
6279 fUsMeridian=-2;
6280 }
6281 if (frame=="gal" || frame=="icr" || frame=="ecl")
6282 {
6283 fMeridian=0;
6284 fUsMeridian=-2;
6285 }
6286 if (frame=="hor" || frame=="loc")
6287 {
6288 fMeridian=0;
6289 fUsMeridian=2;
6290 }
6291 }
6292
6293 // Obtain the projected (x,y) position
6294 Double_t x=0;
6295 Double_t y=0;
6296 Project(phi,theta,proj,x,y);
6297
6298 // X-axis inversion of the display
6299 if (fUsMeridian<0) x*=-1.;
6300
6301 Int_t hist=0;
6302 if (proj=="hamh" || proj=="aith" || proj=="merh" || proj=="cylh" || proj=="angh") hist=1;
6303 if (proj=="UTh" || proj=="LTh" || proj=="GSTh" || proj=="LSTh") hist=1;
6304 if (proj=="UYh" || proj=="LYh" || proj=="GSYh" || proj=="LSYh") hist=1;
6305
6306 // Update the display for this signal position
6307
6308 // Create a new canvas if needed
6309 if (!fCanvas || !(gROOT->GetListOfCanvases()->FindObject("NcAstrolab"))) fCanvas=new TCanvas("NcAstrolab","Skymap");
6310
6311 // Construct the various strings for this map
6312 TString titleup; // The upper title string
6313 TString titlelow; // The lower title string
6314 TString sleft; // The most left coordinate indicator
6315 TString sright; // The most right coordinate indicator
6316 TString sup; // The most upper coordinate indicator
6317 TString slow; // The most lower coordinate indicator
6318 sup="90#circ";
6319 slow="-90#circ";
6320 if (name!="")
6321 {
6322 titleup=name;
6323 titleup+=" ";
6324 }
6325 if (frame=="equ")
6326 {
6327 titleup+="Geocentric Equatorial (";
6328 titleup+=mode;
6329 if (mode=="J") titleup+="2000";
6330 if (mode=="B") titleup+="1950";
6331 titleup+=") ";
6332 }
6333 if (frame=="gal") titleup+="Heliocentric Galactic";
6334 if (frame=="ecl") titleup+=" Geocentric Ecliptic";
6335 if (frame=="hor") titleup+=" Standard Horizon";
6336 if (frame=="icr") titleup+="Static Barycentric ICRS";
6337 if (frame=="loc")
6338 {
6339 titleup+=" User defined Local";
6340 sup=" 0#circ";
6341 slow="180#circ";
6342 }
6343 titleup+=" Coordinates";
6344 titlelow="Projection : ";
6345 if (proj=="ham" || proj=="hamh") titlelow+="Hammer";
6346 if (proj=="cyl" || proj=="cylh") titlelow+="Cylindrical";
6347 if (proj=="ait" || proj=="aith") titlelow+="Aitoff";
6348 if (proj=="mer" || proj=="merh") titlelow+="Mercator";
6349 if (proj=="ang" || proj=="angh")
6350 {
6351 titlelow+="sin(b) vs. l";
6352 sup=" 1";
6353 slow=" -1";
6354 }
6355 titlelow+=" Central Meridian : ";
6356 Int_t ang,h,m,s,d;
6357 Int_t angmax,hmin,hmax,dmin,dmax;
6358 TString corr;
6359 TString scenter="";
6360 if (frame=="equ")
6361 {
6362 ang=int(ConvertAngle(fMeridian,"rad","hms"));
6363 angmax=ang+120000;
6364 h=ang/10000;
6365 ang=ang%10000;
6366 m=ang/100;
6367 s=ang%100;
6368 titlelow+=h;
6369 titlelow+="h ";
6370 titlelow+=m;
6371 titlelow+="m ";
6372 titlelow+=s;
6373 titlelow+="s";
6374 hmax=angmax/10000;
6375 corr="";
6376 while (hmax>24)
6377 {
6378 hmax-=24;
6379 corr="+";
6380 }
6381 hmin=hmax-24;
6382 while (hmin<-12)
6383 {
6384 hmin+=24;
6385 corr="+";
6386 }
6387 sright+=corr;
6388 if (fUsMeridian<0)
6389 {
6390 sright+=hmin;
6391 }
6392 else
6393 {
6394 sright+=hmax;
6395 }
6396 sright+="h";
6397 if (fUsMeridian<0)
6398 {
6399 sleft+=hmax;
6400 }
6401 else
6402 {
6403 sleft+=hmin;
6404 }
6405 sleft+="h";
6406 scenter+=h;
6407 scenter+="h";
6408 }
6409 else
6410 {
6411 ang=int(ConvertAngle(fMeridian,"rad","dms"));
6412 angmax=ang+1800000;
6413 d=ang/10000;
6414 ang=ang%10000;
6415 m=ang/100;
6416 s=ang%100;
6417 titlelow+=d;
6418 titlelow+="d ";
6419 titlelow+=m;
6420 titlelow+="' ";
6421 titlelow+=s;
6422 titlelow+="\"";
6423 dmax=angmax/10000;
6424 corr="";
6425 while (dmax>360)
6426 {
6427 dmax-=360;
6428 corr="+";
6429 }
6430 dmin=dmax-360;
6431 while (dmin<-180)
6432 {
6433 dmin+=360;
6434 corr="+";
6435 }
6436 sright+=corr;
6437 if (fUsMeridian<0)
6438 {
6439 sright+=dmin;
6440 }
6441 else
6442 {
6443 sright+=dmax;
6444 }
6445 sright+="#circ";
6446 if (fUsMeridian<0)
6447 {
6448 sleft+=dmax;
6449 }
6450 else
6451 {
6452 sleft+=dmin;
6453 }
6454 sleft+="#circ";
6455 scenter+=d;
6456 scenter+="#circ";
6457 }
6458
6459 if (!hist) // 2-D Marker display (i.e. not a histogram)
6460 {
6461 TMarker* marker=0;
6462 // Remove existing markers, grid and outline from display if needed
6463 if (clr==1 || proj!=fProj)
6464 {
6465 if (fMarkers)
6466 {
6467 delete fMarkers;
6468 fMarkers=0;
6469 }
6470 fCanvas->Clear();
6471 fProj=proj;
6472 }
6473
6474 // Create a new display if needed
6475 if (!fMarkers)
6476 {
6477 fMarkers=new TObjArray();
6478 fMarkers->SetOwner();
6479
6480 // Set canvas range, header and axes
6481 Float_t xup=2; // Maximal x coordinate of the projection
6482 Float_t yup=1; // maximal y coordinate of the projection
6483 Float_t xlow=-xup;
6484 Float_t ylow=-yup;
6485 Float_t xmargin=0.5; // X margin for canvas size
6486 Float_t ymargin=0.3; // Y margin for canvas size
6487 fCanvas->Range(xlow-xmargin,ylow-ymargin,xup+xmargin,yup+ymargin);
6488
6489 // The ellipse outline with the skymap c.q. projection grid
6490 if (proj=="ham" || proj=="ait")
6491 {
6492 // Draw ellips outline
6493 TEllipse* outline=new TEllipse(0,0,xup,yup);
6494 fMarkers->Add(outline);
6495 outline->Draw();
6496 }
6497
6499 // Draw the skymap c.q. projection grid //
6501
6502 // Drawing of the projected meridians every 30 degrees
6503 const Int_t nphi=13;
6504 Double_t gphiarr[nphi]={0,30,60,90,120,150,180,210,240,270,300,330,360};
6505 Double_t gphi=0;
6506 Double_t gtheta=0;
6507 Int_t ndots=100;
6508 Float_t gstep=180./float(ndots);
6509 Double_t xgrid=0;
6510 Double_t ygrid=0;
6511 for (Int_t iph=0; iph<nphi; iph++)
6512 {
6513 gphi=gphiarr[iph]*pi/180.;
6514 if (frame=="hor") gphi=pi-gphi;
6515 gtheta=pi/2.;
6516 for (Int_t ith=1; ith<ndots; ith++)
6517 {
6518 gtheta=gtheta-(gstep*pi/180.);
6519 Project(gphi,gtheta,proj,xgrid,ygrid);
6520 marker=new TMarker(xgrid,ygrid,fMarkerStyle[3]);
6521 marker->SetMarkerSize(fMarkerSize[3]);
6522 marker->SetMarkerColor(fMarkerColor[3]);
6523 fMarkers->Add(marker);
6524 marker->Draw();
6525 }
6526 }
6527
6528 // Drawing of the projected latitude circles every 15 degrees
6529 const Int_t nth=10;
6530 Double_t gtharr[nth]={15,30,45,60,75,105,120,135,150,165};
6531 gphi=0;
6532 gtheta=0;
6533 gstep=360./float(ndots);
6534 TString gs;
6535 Int_t igs=0;
6536 TLatex* lgs=0;
6537 Double_t xtext=0;
6538 Double_t ytext=0;
6539 for (Int_t ith=0; ith<nth; ith++)
6540 {
6541 gtheta=pi/2.-(gtharr[ith]*pi/180.);
6542 igs=int(90.-gtharr[ith]);
6543 if (frame=="loc") igs=int(gtharr[ith]);
6544 gs="";
6545 gs+=igs;
6546 gs+="#circ";
6547 xtext=0;
6548 for (Int_t iphi=1; iphi<ndots; iphi++)
6549 {
6550 gphi=gphi+gstep;
6551 Project(gphi,gtheta,proj,xgrid,ygrid);
6552 marker=new TMarker(xgrid,ygrid,fMarkerStyle[3]);
6553 marker->SetMarkerSize(fMarkerSize[3]);
6554 marker->SetMarkerColor(fMarkerColor[3]);
6555 if (xgrid<xtext)
6556 {
6557 xtext=xgrid;
6558 ytext=ygrid;
6559 }
6560 fMarkers->Add(marker);
6561 marker->Draw();
6562 }
6563 lgs=new TLatex;
6564 fMarkers->Add(lgs);
6565 if (ytext>0)
6566 {
6567 if (proj=="ham" || proj=="ait")
6568 {
6569 lgs->DrawLatex(xtext-0.25,ytext,gs.Data());
6570 }
6571 else
6572 {
6573 lgs->DrawLatex(xtext-0.4,ytext-0.02,gs.Data());
6574 }
6575 }
6576 else
6577 {
6578 if (proj=="ham" || proj=="ait")
6579 {
6580 lgs->DrawLatex(xtext-0.3,ytext-0.1,gs.Data());
6581 }
6582 else
6583 {
6584 lgs->DrawLatex(xtext-0.4,ytext-0.02,gs.Data());
6585 }
6586 }
6587 }
6588
6589 // The horizontal and vertical axes
6590 TLine* line=new TLine(xlow,0,xup,0);
6591 fMarkers->Add(line);
6592 line->Draw();
6593 line=new TLine(0,yup,0,ylow);
6594 fMarkers->Add(line);
6595 line->Draw();
6596
6597 // The header and footer text
6598 TLatex* header=new TLatex;
6599 fMarkers->Add(header);
6600 header->SetTextAlign(21); // Text will be horizontally centered
6601 header->DrawLatex(0,yup+0.2,titleup.Data());
6602 TLatex* footer=new TLatex;
6603 fMarkers->Add(footer);
6604 footer->SetTextAlign(21); // Text will be horizontally centered
6605 footer->DrawLatex(0,ylow-0.25,titlelow.Data());
6606
6607 // The left side angular value indicator
6608 TLatex* left=new TLatex;
6609 fMarkers->Add(left);
6610 if (proj=="ham" || proj=="ait")
6611 {
6612 left->DrawLatex(xlow-0.4,0,sleft.Data());
6613 }
6614 else
6615 {
6616 left->DrawLatex(xlow-0.15,yup+0.05,sleft.Data());
6617 }
6618 // The right side angular value indicator
6619 TLatex* right=new TLatex;
6620 fMarkers->Add(right);
6621 if (proj=="ham" || proj=="ait")
6622 {
6623 right->DrawLatex(xup+0.1,0,sright.Data());
6624 }
6625 else
6626 {
6627 right->DrawLatex(xup-0.1,yup+0.05,sright.Data());
6628 }
6629 // The upper angular value indicator
6630 TLatex* up=new TLatex;
6631 fMarkers->Add(up);
6632 if (proj=="ham" || proj=="ait")
6633 {
6634 up->DrawLatex(-0.1,yup+0.05,sup.Data());
6635 }
6636 else
6637 {
6638 up->DrawLatex(-0.1,yup+0.05,scenter.Data());
6639 if (proj!="ang")
6640 {
6641 up=new TLatex;
6642 fMarkers->Add(up);
6643 up->DrawLatex(xlow-0.4,yup-0.04,sup.Data());
6644 }
6645 }
6646 // The lower angular value indicator
6647 TLatex* low=new TLatex;
6648 fMarkers->Add(low);
6649 if (proj=="ham" || proj=="ait")
6650 {
6651 low->DrawLatex(-0.15,ylow-0.15,slow.Data());
6652 }
6653 else
6654 {
6655 if (proj!="ang") low->DrawLatex(xlow-0.4,ylow,slow.Data());
6656 }
6657
6659 // Indicate the Galactic Center //
6661
6662 // Add the Galactic Center temporarily as a reference signal for coordinate retrieval
6663 sx=SetSignal(1,0,"deg",0,"deg","gal",0,-1,"J","GC",0);
6664 Int_t idx=fRefs->IndexOf(sx);
6665 idx++;
6666 Nc3Vector rgc;
6667 sx=GetSignal(rgc,frame,mode,ts,idx,0);
6668 if (sx)
6669 {
6670 Double_t thetagc=0;
6671 Double_t phigc=0;
6672 if (frame=="equ" || frame=="gal" || frame=="icr" || frame=="ecl" || frame=="loc")
6673 {
6674 thetagc=(pi/2.)-rgc.GetX(2,"sph","rad");
6675 phigc=rgc.GetX(3,"sph","rad");
6676 }
6677 if (frame=="hor")
6678 {
6679 thetagc=(pi/2.)-rgc.GetX(2,"sph","rad");
6680 phigc=pi-rgc.GetX(3,"sph","rad");
6681 }
6682 // Obtain the projected (x,y) position
6683 Double_t xgc=0;
6684 Double_t ygc=0;
6685 Project(phigc,thetagc,proj,xgc,ygc);
6686 if (fUsMeridian<0) xgc*=-1.;
6687 marker=new TMarker(xgc,ygc,fMarkerStyle[2]);
6688 marker->SetMarkerSize(fMarkerSize[2]);
6689 marker->SetMarkerColor(fMarkerColor[2]);
6690 fMarkers->Add(marker);
6691 marker->Draw();
6692 // Remove the temporary Galactic Center object again
6693 RemoveSignal(idx,0,0);
6694 }
6695 }
6696
6697 // Indicate the measurement(s) or reference signal(s) on the display
6698 marker=new TMarker(x,y,fMarkerStyle[type]);
6699 marker->SetMarkerSize(fMarkerSize[type]);
6700 marker->SetMarkerColor(fMarkerColor[type]);
6701 fMarkers->Add(marker);
6702 marker->Draw();
6703 }
6704 else if (hist==1) // 2-D display via histogram
6705 {
6706 Float_t xfac=90;
6707 Float_t yfac=90;
6708 if (frame=="equ") xfac=6;
6709 if (proj=="angh") yfac=1;
6710 // Reset the histogram if needed
6711 if (clr==1 || proj!=fProj || !fHist[type])
6712 {
6713 if (clr==1 || proj!=fProj)
6714 {
6715 fCanvas->Clear();
6716 fCanvas->SetGrid();
6717 for (Int_t i=0; i<2; i++)
6718 {
6719 if (fHist[i])
6720 {
6721 fHist[i]->Delete();
6722 fHist[i]=0;
6723 }
6724 }
6725 }
6726 if (!fHist[type]) fHist[type]=new TH2F();
6727 fHist[type]->Reset();
6728 fHist[type]->SetMarkerStyle(fMarkerStyle[type]);
6729 fHist[type]->SetMarkerSize(fMarkerSize[type]);
6730 fHist[type]->SetMarkerColor(fMarkerColor[type]);
6731 TString title=titleup;
6732 title+=" ";
6733 title+=titlelow;
6734 fHist[type]->SetNameTitle("SkyMap",title.Data());
6735 fHist[type]->GetXaxis()->SetTitle("Degrees from central Meridian");
6736 if (proj=="angh")
6737 {
6738 fHist[type]->SetBins(1000,-181,181,100,-1.1,1.1);
6739 fHist[type]->GetYaxis()->SetTitle("sin(b)");
6740 }
6741 else
6742 {
6743 fHist[type]->SetBins(1000,-181,181,500,-91,91);
6744 fHist[type]->GetYaxis()->SetTitle("Projected Latitude in degrees");
6745 }
6746 if (frame=="equ")
6747 {
6748 fHist[type]->GetXaxis()->SetTitle("Hours from central Meridian");
6749 if (proj=="angh")
6750 {
6751 fHist[type]->SetBins(200,-12.1,12.1,100,-1.1,1.1);
6752 if (frame=="equ") fHist[type]->GetYaxis()->SetTitle("sin(#delta)");
6753 }
6754 else
6755 {
6756 fHist[type]->SetBins(200,-12.1,12.1,500,-91,91);
6757 if (frame=="equ") fHist[type]->GetYaxis()->SetTitle("Projected Declination in degrees");
6758 }
6759 }
6760 if (frame=="hor")
6761 {
6762 if (proj=="angh")
6763 {
6764 fHist[type]->GetYaxis()->SetTitle("sin(alt)=cos(zenith)");
6765 }
6766 else
6767 {
6768 fHist[type]->GetYaxis()->SetTitle("Projected Altitude in degrees");
6769 }
6770 }
6771 if (frame=="loc")
6772 {
6773 if (proj=="angh")
6774 {
6775 fHist[type]->GetYaxis()->SetTitle("cos(#theta)=sin(b)");
6776 }
6777 else
6778 {
6779 fHist[type]->GetYaxis()->SetTitle("Projected degrees from the equator");
6780 }
6781 }
6782 fProj=proj;
6783 }
6784
6785 if (proj=="merh")
6786 {
6787 fHist[type]->Fill(x*xfac,theta*180./pi);
6788 }
6789 else if (proj=="hamh" || proj=="aith" || proj=="cylh" || proj=="angh")
6790 {
6791 fHist[type]->Fill(x*xfac,y*yfac);
6792 }
6793 else if (proj=="UTh" || proj=="LTh" || proj=="GSTh" || proj=="LSTh") // The 24 hour day view
6794 {
6795 // Set histogram binning and axes attributes
6796 fHist[type]->SetBins(100,0,24,181,-90.5,90.5);
6797 if (!ts) ts=(NcTimestamp*)this;
6798 NcTimestamp tx=(*ts);
6799 Double_t toffset=GetLabTimeOffset();
6800 TString title="Day view";
6801 if (name!="")
6802 {
6803 title+=" of ";
6804 title+=name;
6805 }
6806 title+=" at ";
6807 title+=GetName();
6808 title+=" on ";
6809 TString date;
6810 ts->GetDayTimeString("UT",0,0,&date);
6811 title+=date;
6812 TString tmode="UT";
6813 if (proj=="LTh") tmode="LMT";
6814 if (proj=="GSTh")
6815 {
6816 tmode="GMST";
6817 if (mode=="T") tmode="GAST";
6818 }
6819 if (proj=="LSTh")
6820 {
6821 tmode="LMST";
6822 if (mode=="T") tmode="LAST";
6823 }
6824 if (proj=="UTh") title+=";Universal Time";
6825 if (proj=="LTh") title+=";Local Time";
6826 if (proj=="GSTh") title+=";Greenwich Sidereal Time";
6827 if (proj=="LSTh") title+=";Local Sidereal Time";
6828 if (proj!="UTh")
6829 {
6830 title+=" (";
6831 title+=tmode;
6832 title+=")";
6833 }
6834 title+=" in hours;";
6835 TString ytitle="Declination ";
6836 if (frame=="equ" && mode=="J") ytitle+="(J2000)";
6837 if (frame=="equ" && mode=="B") ytitle+="(B1950)";
6838 if (frame=="equ" && mode=="M") ytitle+="(Mean)";
6839 if (frame=="equ" && mode=="T") ytitle+="(True)";
6840 if (frame=="gal") ytitle="Galactic latitude";
6841 if (frame=="ecl") ytitle="Geocentric Ecliptic latitude";
6842 if (frame=="hor") ytitle="Horizon altitude";
6843 if (frame=="icr") ytitle="ICRS latitude";
6844 if (frame=="loc") ytitle="Angle w.r.t. local frame equator";
6845 ytitle+=" in degrees";
6846 title+=ytitle;
6847 fHist[type]->SetTitle(title);
6848 fHist[type]->SetStats(kFALSE);
6849
6850 // Fill the day view histogram
6851 Double_t hour=0;
6852 Double_t d,a,b;
6853 for (Int_t i=0; i<24; i++)
6854 {
6855 if (tmode=="UT") hour=tx.GetUT();
6856 if (tmode=="LMT") hour=tx.GetLT(toffset);
6857 if (tmode=="GMST") hour=tx.GetGMST();
6858 if (tmode=="GAST") hour=tx.GetGAST();
6859 if (tmode=="LMST") hour=tx.GetLMST(toffset);
6860 if (tmode=="LAST") hour=tx.GetLAST(toffset);
6861
6862 // Get coordinates at this time step
6863 GetSignal(d,a,"deg",b,"deg",frame,&tx,jref,mode,type);
6864
6865 if (frame=="hor") b=90.-b;
6866 if (frame=="loc") b=90.-a;
6867
6868 fHist[type]->Fill(hour,b);
6869
6870 tx.Add(1); // Add 1 hour for each time step
6871 }
6872
6873 // Restore the original timestamp for Solar system objects
6874 SetSolarSystem(namesave,&tsave,type);
6875 }
6876 else if (proj=="UYh" || proj=="LYh" || proj=="GSYh" || proj=="LSYh") // The day of the year view
6877 {
6878 // Set histogram binning and axes attributes
6879 fHist[type]->SetBins(1500,0,370,181,-90.5,90.5);
6880 if (!ts) ts=(NcTimestamp*)this;
6881 NcTimestamp tx=(*ts);
6882 Double_t toffset=GetLabTimeOffset();
6883 TString year="";
6884 year+=int(ts->GetEpoch("J"));
6885 TString tmode="UT";
6886 if (proj=="LYh") tmode="LMT";
6887 if (proj=="GSYh")
6888 {
6889 tmode="GMST";
6890 if (mode=="T") tmode="GAST";
6891 }
6892 if (proj=="LSYh")
6893 {
6894 tmode="LMST";
6895 if (mode=="T") tmode="LAST";
6896 }
6897 TString time;
6898 if (proj=="UYh" || proj=="GSYh") ts->GetDayTimeString(tmode,0,0,0,&time);
6899 if (proj=="LYh" || proj=="LSYh") ts->GetDayTimeString(tmode,0,toffset,0,&time);
6900
6901 TString title="Year view";
6902 if (name!="")
6903 {
6904 title+=" of ";
6905 title+=name;
6906 }
6907 title+=" at ";
6908 title+=GetName();
6909 title+=" in ";
6910 title+=year;
6911 title+=" at ";
6912 title+=time;
6913 title+=";Day of the year;";
6914 TString ytitle="Declination ";
6915 if (frame=="equ" && mode=="J") ytitle+="(J2000)";
6916 if (frame=="equ" && mode=="B") ytitle+="(B1950)";
6917 if (frame=="equ" && mode=="M") ytitle+="(Mean)";
6918 if (frame=="equ" && mode=="T") ytitle+="(True)";
6919 if (frame=="gal") ytitle="Galactic latitude";
6920 if (frame=="ecl") ytitle="Geocentric Ecliptic latitude";
6921 if (frame=="hor") ytitle="Horizon altitude";
6922 if (frame=="icr") ytitle="ICRS latitude";
6923 if (frame=="loc") ytitle="Angle w.r.t. local frame equator";
6924 ytitle+=" in degrees";
6925 title+=ytitle;
6926 fHist[type]->SetTitle(title);
6927 fHist[type]->SetStats(kFALSE);
6928
6929 // Fill the year view histogram
6930 // Start at 01-jan 00:00:00h for the corresponding year at the selected location
6931 // and then set the time according to the specified timestamp
6932 Double_t hour=0;
6933 if (proj=="UYh" || proj=="GSYh") // Location is Greenwich
6934 {
6935 tx.SetUT(year.Atoi(),1,1,"00:00:00");
6936 hour=ts->GetUT();
6937 }
6938 if (proj=="LYh" || proj=="LSYh") // The lab location
6939 {
6940 tx.SetLT(toffset,year.Atoi(),1,1,"00:00:00");
6941 hour=ts->GetLT(toffset);
6942 }
6943 tx.Add(hour); // Set the selected time
6944
6945 Double_t d,a,b;
6946 Int_t day=0;
6947 for (Int_t i=0; i<367; i++)
6948 {
6949
6950 // Get coordinates at this time step
6951 GetSignal(d,a,"deg",b,"deg",frame,&tx,jref,mode,type);
6952
6953 if (frame=="hor") b=90.-b;
6954 if (frame=="loc") b=90.-a;
6955
6956 if (proj=="UYh" || proj=="GSYh") day=tx.GetDayOfYear();
6957 if (proj=="LYh" || proj=="LSYh") day=tx.GetDayOfYear(kFALSE,toffset);
6958
6959 fHist[type]->Fill(day,b);
6960
6961 tx.Add(24); // Add 1 day (= 24 hours) for each time step
6962 }
6963
6964 // Restore the original timestamp for Solar system objects
6965 SetSolarSystem(namesave,&tsave,type);
6966 }
6967
6968 // Draw the selected histogram
6969 if ((!type && fHist[1]) || (type && fHist[0]))
6970 {
6971 fHist[type]->Draw("same");
6972 }
6973 else
6974 {
6975 fHist[type]->Draw();
6976
6977 // Draw a horizontal thick line to mark the horizon c.q. equator for the day and year views
6978 if (proj=="UTh" || proj=="LTh" || proj=="GSTh" || proj=="LSTh" ||
6979 proj=="UYh" || proj=="LYh" || proj=="GSYh" || proj=="LSYh")
6980 {
6981 if (!fMarkers)
6982 {
6983 fMarkers=new TObjArray();
6984 fMarkers->SetOwner();
6985 }
6986 TLine* line=0;
6987 if (proj=="UTh" || proj=="LTh" || proj=="GSTh" || proj=="LSTh") line=new TLine(0,0,24,0);
6988 if (proj=="UYh" || proj=="LYh" || proj=="GSYh" || proj=="LSYh") line=new TLine(0,0,370,0);
6989 if (line)
6990 {
6991 line->SetLineWidth(3);
6992 fMarkers->Add(line);
6993 line->Draw();
6994 }
6995 }
6996 }
6997 }
6998}
6999
7000void NcAstrolab::DisplaySignal(TString frame,TString mode,NcTimestamp* ts,TString name,TString proj,Int_t clr,Int_t type)
7001{
7091
7092 // Create a signal for a solar system object if needed
7093 Double_t d,a,b;
7094 GetSignal(d,a,"deg",b,"deg",frame,ts,name,mode,type);
7095
7096 Int_t j=GetSignalIndex(name,type);
7097 if (j>0)
7098 {
7099 if (type) j=-j;
7100 DisplaySignal(frame,mode,ts,j,proj,clr,name);
7101 }
7102
7103 // Update the canvas so that the Skymap GUI immediately shows the result
7104 if (fCanvas) fCanvas->Update();
7105}
7106
7107void NcAstrolab::DisplaySignals(TString frame,TString mode,NcTimestamp* ts,TString proj,Int_t clr,Int_t nmax,Int_t j,Int_t type,TString name)
7108{
7203
7204 NcSignal* sx=0;
7205 TString namex="";
7206 NcTimestamp* tx=0;
7207 Int_t jdisp=0;
7208
7209 // Display stored reference signals
7210 if (fRefs && type<=0)
7211 {
7212 // Use timestamp of j-th measurement if requested
7213 if (j>0)
7214 {
7215 sx=GetSignal(j,1);
7216 if (sx) tx=sx->GetTimestamp();
7217 }
7218
7219 // Use the provided timestamp
7220 if (!j || !tx) tx=ts;
7221
7222 // Use the current lab timestamp if no timestamp selected
7223 if (!tx) tx=(NcTimestamp*)this;
7224
7225 jdisp=0;
7226 for (Int_t i=1; i<=fRefs->GetSize(); i++)
7227 {
7228 sx=GetSignal(i,0);
7229 if (!sx) continue;
7230
7231 jdisp++;
7232 if (nmax>=0 && jdisp>nmax) break;
7233
7234 // Check for the name pattern
7235 namex=sx->GetName();
7236 if (name!="*" && !namex.Contains(name)) continue;
7237
7238 // Use the actual timestamp of the reference signal
7239 if (j<0)
7240 {
7241 tx=sx->GetTimestamp();
7242 if (!tx) tx=ts;
7243 if (!tx) tx=(NcTimestamp*)this;
7244 }
7245
7246 if (name=="*")
7247 {
7248 DisplaySignal(frame,mode,tx,i,proj,clr);
7249 }
7250 else
7251 {
7252 DisplaySignal(frame,mode,tx,i,proj,clr,name);
7253 }
7254 clr=0; // No display clear for subsequent signals
7255 }
7256 }
7257
7258 // Display all stored measurements
7259 if (fSigs && type)
7260 {
7261 jdisp=0;
7262 for (Int_t j=1; j<=fSigs->GetSize(); j++)
7263 {
7264 sx=GetSignal(j,1);
7265 if (!sx) continue;
7266
7267 jdisp++;
7268 if (nmax>=0 && jdisp>nmax) break;
7269
7270 // Check for the name pattern
7271 namex=sx->GetName();
7272 if (name!="*" && !namex.Contains(name)) continue;
7273
7274 tx=sx->GetTimestamp();
7275 if (!tx) tx=ts;
7276 if (!tx) tx=(NcTimestamp*)this;
7277 if (name=="*")
7278 {
7279 DisplaySignal(frame,mode,tx,-j,proj,clr);
7280 }
7281 else
7282 {
7283 DisplaySignal(frame,mode,tx,-j,proj,clr,name);
7284 }
7285 clr=0; // No display clear for subsequent signals
7286 }
7287 }
7288
7289 // Update the canvas so that the Skymap GUI immediately shows the result
7290 if (fCanvas) fCanvas->Update();
7291}
7292
7293void NcAstrolab::SetMarkerSize(Float_t size,Int_t type)
7294{
7306
7307 if (type<0 || type >3) return;
7308
7309 fMarkerSize[type]=size;
7310}
7311
7312void NcAstrolab::SetMarkerStyle(Int_t style,Int_t type)
7313{
7325
7326 if (type<0 || type >3) return;
7327
7328 fMarkerStyle[type]=style;
7329}
7330
7331void NcAstrolab::SetMarkerColor(Int_t color,Int_t type)
7332{
7344
7345 if (type<0 || type >3) return;
7346
7347 fMarkerColor[type]=color;
7348}
7349
7350void NcAstrolab::SetCentralMeridian(Int_t mode,Double_t phi,TString u)
7351{
7375
7376 fMeridian=ConvertAngle(phi,u,"rad");
7377 fUsMeridian=0;
7378 if (mode>0) fUsMeridian=1;
7379 if (mode<0) fUsMeridian=-1;
7380 Double_t pi=acos(-1.);
7381 Double_t twopi=2.*pi;
7382 // Set range to 0 <= meridian < 2pi
7383 while (fMeridian>=twopi)
7384 {
7385 fMeridian-=twopi;
7386 }
7387 while (fMeridian<0)
7388 {
7389 fMeridian+=twopi;
7390 }
7391 // Prevent accuracy problems
7392 if (fMeridian>0) fMeridian+=1.e-6;
7393}
7394
7395void NcAstrolab::Project(Double_t l,Double_t b,TString proj,Double_t& x,Double_t& y)
7396{
7427
7428 Double_t pi=acos(-1.);
7429
7430 // Subtract central meridian from longitude
7431 l-=fMeridian;
7432
7433 // Take l between -180 and 180 degrees
7434 while (l>pi)
7435 {
7436 l-=2.*pi;
7437 }
7438 while (l<-pi)
7439 {
7440 l+=2.*pi;
7441 }
7442
7443 x=0;
7444 y=0;
7445
7446 // Convert (l,b) to (x,y) with -2 < x <= 2
7447 if (proj=="cyl" || proj=="cylh") ProjectCylindrical(l,b,x,y);
7448 if (proj=="ham" || proj=="hamh") ProjectHammer(l,b,x,y);
7449 if (proj=="ait" || proj=="aith") ProjectAitoff(l,b,x,y);
7450 if (proj=="mer" || proj=="merh") ProjectMercator(l,b,x,y);
7451 if (proj=="ang" || proj=="angh")
7452 {
7453 x=2.*l/pi;
7454 y=sin(b);
7455 }
7456}
7457
7458void NcAstrolab::ProjectCylindrical(Double_t l,Double_t b,Double_t& x, Double_t& y)
7459{
7468
7469 Double_t pi=acos(-1.);
7470 x=2.*l/pi;
7471 y=2.*b/pi;
7472}
7473
7474void NcAstrolab::ProjectHammer(Double_t l,Double_t b,Double_t& x,Double_t& y)
7475{
7485
7486 Double_t k=1./sqrt(1.+cos(b)*cos(l/2.));
7487 x=2.*k*cos(b)*sin(l/2.);
7488 y=k*sin(b);
7489}
7490
7491void NcAstrolab::ProjectAitoff(Double_t l,Double_t b,Double_t& x,Double_t& y)
7492{
7501
7502 Double_t pi=acos(-1.);
7503 x=0;
7504 y=0;
7505 Double_t k=acos(cos(b)*cos(l/2.));
7506 if(sin(k)!=0)
7507 {
7508 x=4.*k*cos(b)*sin(l/2.)/(pi*sin(k));
7509 y=2.*k*sin(b)/(pi*sin(k));
7510 }
7511}
7512
7513void NcAstrolab::ProjectMercator(Double_t l,Double_t b,Double_t& x,Double_t& y)
7514{
7529
7530 Double_t pi=acos(-1.);
7531 Double_t bcut=85.051*pi/180.; // Latitude cut off value in radians
7532
7533 x=2.*l/pi;
7534 y=0;
7535 if (b > bcut) b=bcut;
7536 if (b < -bcut) b=-bcut;
7537 y=0.5*log((1.+sin(b))/(1.-sin(b)))/pi;
7538}
7539
7540void NcAstrolab::SetPhysicalParameter(TString name,Double_t value)
7541{
7579
7580 // Variable to correct conversion factors when a parameter is modified
7581 Double_t frac=1;
7582
7583 if (name=="SpeedC")
7584 {
7585 frac=value/fSpeedC;
7586 fSpeedC=value;
7587 fMe*=frac*frac;
7588 fMmu*=frac*frac;
7589 fMtau*=frac*frac;
7590 fAmu*=frac*frac;
7591 fMp*=frac*frac;
7592 fMn*=frac*frac;
7593 fMW*=frac*frac;
7594 fMZ*=frac*frac;
7595 fHbarc*=frac;
7596 fHbarc2*=pow(frac,2.);
7597 }
7598 if (name=="Qe")
7599 {
7600 frac=value/fQe;
7601 fQe=value;
7602 fMe/=frac;
7603 fMmu/=frac;
7604 fMtau/=frac;
7605 fAmu/=frac;
7606 fMp/=frac;
7607 fMn/=frac;
7608 fMW/=frac;
7609 fMZ/=frac;
7610 fHbar/=frac;
7611 fHbarc/=frac;
7612 fHbarc2/=pow(frac,2.);
7613 }
7614 if (name=="Me") fMe=value;
7615 if (name=="Mmu") fMmu=value;
7616 if (name=="Mtau") fMtau=value;
7617 if (name=="Amu")
7618 {
7619 frac=value/fAmu;
7620 fAmu=value;
7621 fMp*=frac;
7622 fMn*=frac;
7623 }
7624 if (name=="Mp") fMp=value;
7625 if (name=="Mn") fMn=value;
7626 if (name=="MW") fMW=value;
7627 if (name=="GammaW") fGammaW=value;
7628 if (name=="MZ") fMZ=value;
7629 if (name=="GammaZ") fGammaZ=value;
7630 if (name=="AlphaEM") fAlphaEM=value;
7631 if (name=="Fermi") fFermi=value;
7632 if (name=="Planck")
7633 {
7634 frac=value/fPlanck;
7635 fPlanck=value;
7636 fHbar*=frac;
7637 fHbarc*=frac;
7638 fFermi/=pow(frac,3.);
7639 }
7640 if (name=="Boltz") fBoltz=value;
7641 if (name=="Newton")
7642 {
7643 frac=value/fNewton;
7644 fNewton=value;
7645 fGn*=frac;
7646 }
7647 if (name=="Gn") fGn=value;
7648 if (name=="Au") fAu=value;
7649 if (name=="Pc") fPc=value;
7650 if (name=="Hubble") fHubble=value;
7651 if (name=="OmegaM") fOmegaM=value;
7652 if (name=="OmegaR") fOmegaR=value;
7653 if (name=="OmegaL") fOmegaL=value;
7654 if (name=="OmegaB") fOmegaB=value;
7655 if (name=="OmegaC") fOmegaC=value;
7656}
7657
7658Double_t NcAstrolab::GetPhysicalParameter(TString name) const
7659{
7681
7682 Double_t val=0;
7683
7684 // Standard parameters
7685 if (name=="SpeedC") return fSpeedC;
7686 if (name=="Qe") return fQe;
7687 if (name=="Me") return fMe;
7688 if (name=="Mmu") return fMmu;
7689 if (name=="Mtau") return fMtau;
7690 if (name=="Amu") return fAmu;
7691 if (name=="Mp") return fMp;
7692 if (name=="Mn") return fMn;
7693 if (name=="MW") return fMW;
7694 if (name=="GammaW") return fGammaW;
7695 if (name=="GammaZ") return fGammaZ;
7696 if (name=="AlphaEM") return fAlphaEM;
7697 if (name=="Fermi") return fFermi;
7698 if (name=="Planck") return fPlanck;
7699 if (name=="Boltz") return fBoltz;
7700 if (name=="Newton") return fNewton;
7701 if (name=="Gn") return fGn;
7702 if (name=="Au") return fAu;
7703 if (name=="Pc") return fPc;
7704 if (name=="Hubble") return fHubble;
7705 if (name=="OmegaM") return fOmegaM;
7706 if (name=="OmegaR") return fOmegaR;
7707 if (name=="OmegaL") return fOmegaL;
7708 if (name=="OmegaB") return fOmegaB;
7709 if (name=="OmegaC") return fOmegaC;
7710
7711 // Derived parameters
7712 if (name=="Hbar") return fHbar;
7713 if (name=="Hbarc") return fHbarc;
7714 if (name=="Hbarc2") return fHbarc2;
7715 if (name=="Mnucl")
7716 {
7717 val=(fMp+fMn)/2.;
7718 return val;
7719 }
7720 if (name=="Sin2w")
7721 {
7722 val=1.-pow(fMW/fMZ,2.);
7723 return val;
7724 }
7725 if (name=="Jy") return 1e-23;
7726 if (name=="Erg")
7727 {
7728 val=1e-7/(fQe*1e9);
7729 return val;
7730 }
7731
7732 // Unknown parameter
7733 return 0;
7734}
7735
7736Double_t NcAstrolab::GetPhysicalDistance(Double_t z,TString u,Int_t t) const
7737{
7771
7772 if (z<=0 || fHubble<=0) return 0;
7773
7774 Double_t c=fSpeedC/1000.; // Lightspeed in km/s
7775
7776 TF1 f("f","1./sqrt([0]*pow((1.+x),4)+[1]*pow((1.+x),3)+[2])");
7777
7778 f.SetParameter(0,fOmegaR);
7779 f.SetParameter(1,fOmegaM);
7780 f.SetParameter(2,fOmegaL);
7781 f.SetRange(0,z);
7782
7783 Double_t dist=f.Integral(0,z);
7784 dist*=c/fHubble; // The distance in Mpc
7785
7786 Double_t distm=dist*1e6*fPc; // corresponding distance in meter
7787
7788 Double_t val=0;
7789
7790 if (u=="Gpc") val=dist*1e-3;
7791 if (u=="Mpc") val=dist;
7792 if (u=="pc") val=dist*1e6;
7793 if (u=="ly") val=dist*3.26156e6;
7794 if (u=="m") val=distm;
7795 if (u=="km") val=distm*1e-3;
7796 if (u=="cm") val=distm*1e2;
7797
7798 if (!t) val=val/(z+1.);
7799
7800 return val;
7801}
7802
7803Double_t NcAstrolab::GetProperDistance(Double_t z,TString u,Int_t t) const
7804{
7838
7839 Double_t val=GetPhysicalDistance(z,u,t);
7840
7841 return val;
7842}
7843
7844Double_t NcAstrolab::GetComovingDistance(Double_t z,TString u) const
7845{
7876
7877 Double_t val=GetPhysicalDistance(z,u,1);
7878
7879 return val;
7880}
7881
7882Double_t NcAstrolab::GetLuminosityDistance(Double_t z,TString u) const
7883{
7917
7918 Double_t val=GetPhysicalDistance(z,u,1);
7919 val=val*(z+1.);
7920
7921 return val;
7922}
7923
7924Double_t NcAstrolab::GetLightTravelDistance(Double_t z,TString u) const
7925{
7959
7960 if (z<=0 || fHubble<=0) return 0;
7961
7962 Double_t c=fSpeedC/1000.; // Lightspeed in km/s
7963
7964 TF1 f("f","1./((1.+x)*sqrt([0]*pow((1.+x),4)+[1]*pow((1.+x),3)+[2]))");
7965
7966 f.SetParameter(0,fOmegaR);
7967 f.SetParameter(1,fOmegaM);
7968 f.SetParameter(2,fOmegaL);
7969 f.SetRange(0,z);
7970
7971 Double_t dist=f.Integral(0,z);
7972 dist*=c/fHubble; // The distance in Mpc
7973
7974 Double_t distm=dist*1e6*fPc; // corresponding distance in meter
7975
7976 Double_t val=0;
7977
7978 if (u=="Gpc") val=dist*1e-3;
7979 if (u=="Mpc") val=dist;
7980 if (u=="pc") val=dist*1e6;
7981 if (u=="ly") val=dist*3.26156e6;
7982 if (u=="m") val=distm;
7983 if (u=="km") val=distm*1e-3;
7984 if (u=="cm") val=distm*1e2;
7985
7986 return val;
7987}
7988
7989Double_t NcAstrolab::GetLightTravelTime(Double_t z) const
7990{
8008
8009 Double_t val=GetLightTravelDistance(z,"ly");
8010
8011 return val;
8012}
8013
8014Double_t NcAstrolab::GetHubbleParameter(Double_t z,TString u) const
8015{
8036
8037 if (z<0 || fHubble<=0) return 0;
8038
8039 TF1 f("f","sqrt([0]*pow((1.+x),4)+[1]*pow((1.+x),3)+[2])");
8040
8041 f.SetParameter(0,fOmegaR);
8042 f.SetParameter(1,fOmegaM);
8043 f.SetParameter(2,fOmegaL);
8044 f.SetRange(0,z);
8045
8046 Double_t H=f.Eval(z);
8047 H*=fHubble; // The current Hubble parameter (H0) in km/s per Mpc
8048
8049 Double_t Hm=H/(1e6*fPc); // corresponding H in km/s per meter
8050
8051 Double_t val=0;
8052
8053 if (u=="Gpc") val=H/1e-3;
8054 if (u=="Mpc") val=H;
8055 if (u=="pc") val=H/1e6;
8056 if (u=="ly") val=H/3.26156e6;
8057 if (u=="m") val=Hm;
8058 if (u=="km") val=Hm/1e-3;
8059 if (u=="cm") val=Hm/1e2;
8060
8061 return val;
8062}
8063
8064Double_t NcAstrolab::GetNuclearMass(Int_t Z,Int_t N,Int_t mode) const
8065{
8093
8094 if (Z<0 || N<0) return 0;
8095
8096 Double_t rz=Z;
8097 Double_t rn=N;
8098 Double_t ra=Z+N;
8099
8100 // Coefficients from a recent fit mentioned in Tipler's modern physics (4th ed.) textbook.
8101 // The values in the comment field are the ones of the slides mentioned above.
8102 Double_t a=15.67; //15.835;
8103 Double_t b=17.23; //18.33;
8104 Double_t s=23.2; //23.20;
8105 Double_t d=0.75; //0.714;
8106 Double_t delta=12; //11.2;
8107
8108 Double_t term1=a*ra; // Constant bulk binding energy like cohesion in a liquid
8109 Double_t term2=b*pow(ra,2./3.); // Surface energy of a sphere like surface tension of liquids
8110 Double_t term3=s*pow((rn-rz),2.)/ra; // Symmetry term
8111 Double_t term4=d*pow(rz,2.)/pow(ra,1./3.); // Coulomb term
8112 Double_t term5=0; // Phenomenological correction for light nuclei (pairing energy term)
8113
8114 Int_t oz=Z%2; // Flag (1) for odd Z nuclei
8115 Int_t on=N%2; // Flag (1) for odd N nuclei
8116
8117 if (oz && on) term5=delta/sqrt(ra);
8118 if (!oz && !on) term5=-delta/sqrt(ra);
8119
8120 // Binding energy in MeV
8121 Double_t bnz=term1-term2-term3-term4-term5;
8122
8123 // In case a single nucleon was specified
8124 if ((Z+N)<2)
8125 {
8126 bnz=0;
8127 ra=1;
8128 }
8129
8130 // Nuclear mass in MeV/c^2
8131 Double_t mass=rz*fMp+rn*fMn-bnz;
8132
8133 // Explicit literature values for very light elements
8134 if (Z==1 && N==1) // Deuteron
8135 {
8136 mass=2.013553212712*fAmu;
8137 bnz=rz*fMp+rn*fMn-mass;
8138 }
8139
8140 if (Z==1 && N==2) // Triton
8141 {
8142 mass=3.0155007134*fAmu;
8143 bnz=rz*fMp+rn*fMn-mass;
8144 }
8145
8146 if (Z==2 && N==1) // Helion
8147 {
8148 mass=3.0149322468*fAmu;
8149 bnz=rz*fMp+rn*fMn-mass;
8150 }
8151
8152 if (Z==2 && N==2) // Alpha
8153 {
8154 mass=4.001506179125*fAmu;
8155 bnz=rz*fMp+rn*fMn-mass;
8156 }
8157
8158 Double_t value=0;
8159
8160 switch(mode)
8161 {
8162 case 1 : // Nuclear mass in GeV/c^2
8163 value=mass/1000.;
8164 break;
8165
8166 case -1 : // Nuclear mass in amu
8167 value=mass/fAmu;
8168 break;
8169
8170 case 2 : // Total binding energy in MeV
8171 value=bnz;
8172 break;
8173
8174 case -2 : // Total binding energy in amu
8175 value=bnz/fAmu;
8176 break;
8177
8178 case 3 : // Binding energy per nucleon in MeV
8179 value=bnz/ra;
8180 break;
8181
8182 case -3 : // Binding energy per nucleon in amu
8183 value=bnz/(fAmu*ra);
8184 break;
8185 }
8186
8187 return value;
8188}
8189
8190Double_t NcAstrolab::GetRadiationLength(Double_t Z,Double_t A,Double_t rho) const
8191{
8220
8221 Double_t X0=-1;
8222
8223 if (Z<=0 || A<1 || A<Z) return -1;
8224
8225 X0=716.4*A/(Z*(Z+1.)*(log(287./sqrt(Z))));
8226
8227 Double_t mN=0.001*fGn*fQe/fAmu; // The nucleon mass in gram
8228 if (rho==0) X0=X0/mN;
8229 if (rho>0) X0=X0/rho;
8230
8231 return X0;
8232}
8233
8234Double_t NcAstrolab::GetMeanFreePath(Double_t sigma,Double_t rho,Int_t mode) const
8235{
8270
8271 Double_t lambda=-1;
8272
8273 if (sigma<=0 || rho<=0 || mode<0 || mode>4) return -1;
8274
8275 Double_t mN=0.001*fGn*fQe/fAmu; // The nucleon mass in gram
8276 Double_t n=fabs(rho)/mN; // The number of nucleons per cm^3
8277 if (mode<2) n=rho; // The number of scattering centers per cm^3
8278 sigma=sigma*1e-24; // Convert to cm^2
8279
8280 lambda=1./(sigma*n);
8281
8282 if (mode==1 || mode==4) lambda=lambda*n;
8283 if (mode==3) lambda=lambda*rho;
8284
8285 return lambda;
8286}
8287
8288Double_t NcAstrolab::GetInteractionProbability(Double_t x,Double_t lambda) const
8289{
8320
8321 Double_t prob=-1;
8322
8323 if (x<0 || lambda<=0) return -1;
8324
8325 prob=1.-exp(-x/lambda);
8326
8327 return prob;
8328}
8329
8330Double_t NcAstrolab::GetInteractionProbability(Double_t x,Double_t sigma,Double_t rho,Int_t mode) const
8331{
8363
8364 Double_t prob=-1;
8365
8366 Double_t lambda=GetMeanFreePath(sigma,rho,mode);
8367
8368 if (lambda>0) prob=GetInteractionProbability(x,lambda);
8369
8370 return prob;
8371}
8372
8373Double_t NcAstrolab::GetSurvivalProbability(Double_t x,Double_t lambda) const
8374{
8405
8406 Double_t prob=-1;
8407
8408 if (x<0 || lambda<=0) return -1;
8409
8410 prob=exp(-x/lambda);
8411
8412 return prob;
8413}
8414
8415Double_t NcAstrolab::GetSurvivalProbability(Double_t x,Double_t sigma,Double_t rho,Int_t mode) const
8416{
8448
8449 Double_t prob=-1;
8450
8451 Double_t lambda=GetMeanFreePath(sigma,rho,mode);
8452
8453 if (lambda>0) prob=GetSurvivalProbability(x,lambda);
8454
8455 return prob;
8456}
8457
8458Double_t NcAstrolab::GetShieldingThickness(Double_t prob,Double_t lambda) const
8459{
8487
8488 Double_t x=-1;
8489
8490 if (prob<=0 || prob>1 || lambda<=0) return -1;
8491
8492 x=-lambda*log(prob);
8493
8494 return x;
8495}
8496
8497Double_t NcAstrolab::GetShieldingThickness(Double_t prob,Double_t sigma,Double_t rho,Int_t mode) const
8498{
8527
8528 Double_t x=-1;
8529
8530 if (prob<=0 || prob>1) return -1;
8531
8532 Double_t lambda=GetMeanFreePath(sigma,rho,mode);
8533
8534 if (lambda>0) x=GetShieldingThickness(prob,lambda);
8535
8536 return x;
8537}
8538
8539Double_t NcAstrolab::GetTargetThickness(Double_t prob,Double_t lambda) const
8540{
8568
8569 if (prob<=0 || prob>1 || lambda<=0) return -1;
8570
8571 Double_t p=1.-prob;
8572 Double_t x=GetShieldingThickness(p,lambda);
8573
8574 return x;
8575}
8576
8577Double_t NcAstrolab::GetTargetThickness(Double_t prob,Double_t sigma,Double_t rho,Int_t mode) const
8578{
8607
8608 Double_t x=-1;
8609
8610 if (prob<=0 || prob>1) return -1;
8611
8612 Double_t lambda=GetMeanFreePath(sigma,rho,mode);
8613
8614 Double_t p=1.-prob;
8615 if (lambda>0) x=GetShieldingThickness(p,lambda);
8616
8617 return x;
8618}
8619
8620Double_t NcAstrolab::GetNeutrinoXsection(Int_t mode,Int_t type,Double_t egev,Double_t xscale,Double_t* eprimgev,Double_t* alpha) const
8621{
8668
8669 if (eprimgev) *eprimgev=0;
8670 if (alpha) *alpha=0;
8671 if (!mode || mode>3 || mode<-4 || !type || abs(type)>3) return 0;
8672
8673 const Double_t fnumuccn=6.77e-15; // Nu_mu+Nucleon CC sigma/E in barn/GeV
8674 const Double_t fanumuccn=3.34e-15; // Anti-Nu_mu+Nucleon CC sigma/E in barn/GeV
8675
8676 const Double_t sinw2=GetPhysicalParameter("Sin2w"); // sin^2 of the Weinberg angle
8677
8678 const Double_t fnuetote=0.25+sinw2+4.*pow(sinw2,2.)/3.; // Nu_e+e total sigma/sigma0
8679 const Double_t fanuetote=(1./12.)+(sinw2/3.)+4.*pow(sinw2,2.)/3.; // Anti-Nu_e+e total sigma/sigma0
8680 Double_t fnumucce=1.; // Nu_mu+e CC sigma/sigma0
8681 const Double_t fnumunce=0.25-sinw2+4.*pow(sinw2,2.)/3.; // Nu_mu+e NC sigma/sigma0
8682 const Double_t fanumunce=(1./12.)-(sinw2/3.)+4.*pow(sinw2,2.)/3.; // Anti-Nu_mu+e NC sigma/sigma0
8683 const Double_t f4=1./3.; // Anti-Nu_e+e-->Anti-Nu_mu+mu CC sigma/sigma0
8684
8685 // Parameters for the (anti)neutrino+Nucleon cross section parametrisations of Conolly et al.
8686 const Double_t c0nu=-1.826;
8687 const Double_t c1nu=-17.31;
8688 const Double_t c2nunc=-6.448;
8689 const Double_t c2nucc=-6.406;
8690 const Double_t c3nu=1.431;
8691 const Double_t c4nunc=-18.61;
8692 const Double_t c4nucc=-17.91;
8693 const Double_t c0anu=-1.033;
8694 const Double_t c1anu=-15.95;
8695 const Double_t c2anunc=-7.296;
8696 const Double_t c2anucc=-7.247;
8697 const Double_t c3anu=1.569;
8698 const Double_t c4anunc=-18.30;
8699 const Double_t c4anucc=-17.72;
8700
8701 Double_t rncnu=0.2261/0.7221; // sigma_nc/sigma_cc for Neutrino+Nucleon DIS at 100 GeV
8702 Double_t rncanu=0.1307/0.3747; // sigma_nc/sigma_cc for Anti-neutrino+Nucleon DIS at 100 GeV
8703
8704 // Average inelasticity (y) values from Gandhi et al.
8705 Double_t ynucc[12]={0.483,0.477,0.472,0.426,0.332,0.237,0.250,0.237,0.225,0.216,0.208,0.205};
8706 Double_t ynunc[12]={0.474,0.470,0.467,0.428,0.341,0.279,0.254,0.239,0.227,0.217,0.210,0.207};
8707 Double_t yanucc[12]={0.333,0.340,0.354,0.345,0.301,0.266,0.249,0.237,0.225,0.216,0.208,0.205};
8708 Double_t yanunc[12]={0.350,0.354,0.368,0.358,0.313,0.273,0.253,0.239,0.227,0.217,0.210,0.207};
8709
8710 Double_t loge=log10(egev);
8711 Double_t y=0;
8712 Int_t index=int(loge+0.5);
8713 if (index<1) index=1;
8714 if (index>12) index=12;
8715 if (eprimgev)
8716 {
8717 if (type>0) // Neutrinos
8718 {
8719 if (abs(mode)==1) y=ynucc[index-1];
8720 if (abs(mode)==2) y=ynunc[index-1];
8721 if (mode==3) y=(ynucc[index-1]+rncnu*ynunc[index-1])/(1.+rncnu);
8722 if (mode==-3) y=(ynucc[index-1]+fnumunce*ynunc[index-1])/(1.+fnumunce);
8723 }
8724 else // Anti-neutrinos
8725 {
8726 if (abs(mode)==1) y=yanucc[index-1];
8727 if (abs(mode)==2) y=yanunc[index-1];
8728 if (mode==3) y=(yanucc[index-1]+rncanu*yanunc[index-1])/(1.+rncanu);
8729 if (mode==-3) y=(yanucc[index-1]+fnumunce*yanunc[index-1])/(1.+fnumunce);
8730 }
8731 *eprimgev=egev*(1.-y);
8732 }
8733
8734 if (alpha)
8735 {
8736 Double_t mtarg=fMe;
8737 if (mode>0) mtarg=GetPhysicalParameter("Mnucl");
8738 *alpha=sqrt(2.e-3*mtarg/egev)*y*180./((1.-y)*acos(-1.));
8739 }
8740
8741 Double_t xsec=0;
8742 Double_t fact=0;
8743 Double_t c0=0,c1=0,c2=0,c3=0,c4=0;
8744
8745 if (mode>0) // DIS on Nucleon target
8746 {
8747 if (mode==3) // Total xsec
8748 {
8749 // Recursive invokation for NC+CC cross section
8750 xsec=GetNeutrinoXsection(1,type,egev,xscale);
8751 xsec+=GetNeutrinoXsection(2,type,egev,xscale);
8752 return xsec;
8753 }
8754 if (egev<1e4) // Energy below 10 TeV
8755 {
8756 if (mode==1) // CC xsec
8757 {
8758 fact=fnumuccn;
8759 if (type<0) fact=fanumuccn;
8760 }
8761 if (mode==2) // NC xsec
8762 {
8763 fact=fnumuccn*rncnu;
8764 if (type<0) fact=fanumuccn*rncanu;
8765 }
8766 xsec=fact*egev;
8767 }
8768 else // Energy of 10 TeV and above
8769 {
8770 if (mode==1) // CC xsec
8771 {
8772 if (type>0)
8773 {
8774 c0=c0nu;
8775 c1=c1nu;
8776 c2=c2nucc;
8777 c3=c3nu;
8778 c4=c4nucc;
8779 }
8780 else
8781 {
8782 c0=c0anu;
8783 c1=c1anu;
8784 c2=c2anucc;
8785 c3=c3anu;
8786 c4=c4anucc;
8787 }
8788 }
8789 if (mode==2) // NC xsec
8790 {
8791 if (type>0)
8792 {
8793 c0=c0nu;
8794 c1=c1nu;
8795 c2=c2nunc;
8796 c3=c3nu;
8797 c4=c4nunc;
8798 }
8799 else
8800 {
8801 c0=c0anu;
8802 c1=c1anu;
8803 c2=c2anunc;
8804 c3=c3anu;
8805 c4=c4anunc;
8806 }
8807 }
8808 Double_t lne=log(loge-c0);
8809 Double_t logsigma=c1+c2*lne+c3*pow(lne,2.)+c4/lne; // Log10(sigma) in cm^2
8810 logsigma+=24.;
8811 xsec=pow(10.,logsigma);
8812 }
8813 }
8814 else // Scattering on electron target
8815 {
8816 // Check whether we are in the Glashow resonance regime
8817 Double_t elow=pow((fMW-2.*fGammaW),2.)/(2.e-3*fMe);
8818 Double_t eup=pow((fMW+2.*fGammaW),2.)/(2.e-3*fMe);
8819 if (mode==-3 && type==-1 && egev>elow && egev<eup) // Total xsec at Glashow resonance
8820 {
8821 xsec=5.02e-7/xscale;
8822 if (eprimgev) *eprimgev=0;
8823 if (alpha) *alpha=0;
8824 return xsec;
8825 }
8826
8827 // Check if we are above the kinematical threshold energy for CC scattering
8828 Double_t mlepton=fMe;
8829 if (abs(type)==2) mlepton=fMmu;
8830 if (abs(type)==3) mlepton=fMtau;
8831 Double_t eth=1.e-3*(pow(mlepton,2.)-pow(fMe,2.))/(2.*fMe);
8832
8833 if (egev<eth) // Below CC kinematical threshold
8834 {
8835 fnumucce=0;
8836 if (mode==-1) // CC xsec was requested
8837 {
8838 if (eprimgev) *eprimgev=egev;
8839 if (alpha) *alpha=0;
8840 return 0;
8841 }
8842 }
8843
8844 // The Nu_mu+e CC cross section in barn well above threshold
8845 Double_t sigma0=pow(fFermi,2.)*fHbarc2*2.e-3*fMe*egev/acos(-1.);
8846
8847 if (mode==-1) // CC xsec
8848 {
8849 if (type>1) fact=fnumucce;
8850 }
8851 if (mode==-2) // NC xsec
8852 {
8853 if (type>1) fact=fnumunce;
8854 if (type<-1) fact=fanumunce;
8855 }
8856 if (mode==-3) // Total xsec
8857 {
8858 if (type==1) fact=fnuetote;
8859 if (type==-1) fact=fanuetote;
8860 if (type>1) fact=fnumucce+fnumunce;
8861 if (type<-1) fact=fanumunce;
8862 }
8863 if (mode==-4 && type==-1) fact=f4;
8864 xsec=fact*sigma0;
8865 }
8866
8867 xsec/=xscale;
8868
8869 return xsec;
8870}
8871
8872Double_t NcAstrolab::GetNeutrinoAngle(Double_t E,TString u,Int_t mode,TF1* f)
8873{
8909
8910 Double_t value=-1;
8911
8912 if (E<=0 || mode<0 || mode>2) return value;
8913
8914 // Convert to TeV
8915 E*=0.001;
8916
8917 // The parametrisation (in degrees) for a 1 TeV neutrino
8918 Double_t mean=1.38711583;
8919 Double_t median=0.86842105;
8920 Double_t mpv=0.560150;
8921 Double_t sigma=0.226679;
8922
8923 // Scaling the parameters to the provided neutrino energy
8924 Double_t p=log10(E);
8925 Double_t scale=1./(pow(1.5,p)*sqrt(E));
8926
8927 mean*=scale;
8928 median*=scale;
8929 mpv*=scale;
8930 sigma*=scale;
8931
8932 // Create a normalized Landau distribution template
8933 if (!fNuAngle)
8934 {
8935 fNuAngle=new TF1("NuAngle","TMath::Landau(x,[0],[1],1)",0,90);
8936 fNuAngle->SetTitle("Landau pdf;Neutrino-lepton opening angle in degrees;PDF");
8937 }
8938
8939 // Set the parameters for the Landau parametrization
8940 fNuAngle->SetParameter(0,mpv);
8941 fNuAngle->SetParameter(1,sigma);
8942
8943 // Obtain an opening angle value according to the pdf
8944 Double_t ang=fNuAngle->GetRandom();
8945
8946 if (u=="rad")
8947 {
8948 Double_t fact=acos(-1.)/180.; // Coversion factor degrees->radians
8949 mean*=fact;
8950 median*=fact;
8951 ang*=fact;
8952 }
8953
8954 // Provide the used pdf if requested
8955 if (f) fNuAngle->Copy(*f);
8956
8957 value=mean;
8958 if (mode==1) value=median;
8959 if (mode==2) value=ang;
8960
8961 return value;
8962}
8963
8964void NcAstrolab::RandomPosition(Nc3Vector& v,Double_t thetamin,Double_t thetamax,Double_t phimin,Double_t phimax)
8965{
8981
8982 // If needed, initialise the randomiser with a "date/time driven" seed
8983 // using the timestamp of the moment of this invokation of the member function.
8984 // This will ensure different random sequences if the user repeats analyses
8985 // with identical measurements and reference signals without explicit initialisation
8986 // of the randomiser by the user at the start of the analysis.
8987 if (!fRan) fRan=new NcRandom(-1);
8988
8989 // Generate random angles in the specified range
8990 Double_t pi=acos(-1.);
8991 Double_t cosmax=cos(thetamin*pi/180.);
8992 Double_t cosmin=cos(thetamax*pi/180.);
8993 Double_t cost=fRan->Uniform(cosmin,cosmax);
8994 Double_t theta=acos(cost)*180./pi;
8995 Double_t phi=fRan->Uniform(phimin,phimax);
8996
8997 Double_t norm=1;
8998 if (v.HasVector()) norm=v.GetNorm();
8999
9000 Double_t err[3]={0,0,0};
9001 Int_t ier=0;
9002 if (v.HasErrors())
9003 {
9004 ier=1;
9005 v.GetErrors(err,"car");
9006 }
9007
9008 v.SetVector(norm,theta,phi,"sph","deg");
9009 if (ier) v.SetErrors(err,"car");
9010}
9011
9013{
9032
9033 if (!v.HasVector()) return;
9034
9035 // If needed, initialise the randomiser with a "date/time driven" seed
9036 // using the timestamp of the moment of this invokation of the member function.
9037 // This will ensure different random sequences if the user repeats analyses
9038 // with identical measurements and reference signals without explicit initialisation
9039 // of the randomiser by the user at the start of the analysis.
9040 if (!fRan) fRan=new NcRandom(-1);
9041
9042 Double_t norm=v.GetX(1,"sph","deg");
9043 Double_t theta=v.GetX(2,"sph","deg");
9044 Double_t phi=v.GetX(3,"sph","deg");
9045 Double_t err[3]={0,0,0};
9046 Int_t ier=0;
9047 if (v.HasErrors())
9048 {
9049 ier=1;
9050 v.GetErrors(err,"car");
9051 }
9052 if (norm<=0)
9053 {
9054 norm=1;
9055 err[0]=0;
9056 }
9057 v.SetVector(norm,theta,phi,"sph","deg");
9058
9059 // The smeared position will be generated as if the actual vector "v" coincided with the positive Z-axis.
9060 // The actual smeared position will be obtained via a "backward rotation" to the real frame orientation.
9061
9062 // Determine the rotation matrix for the frame in which "v" coincides with the positive Z-axis.
9063 TRotMatrix m;
9064 m.SetAngles(90.+theta,phi,90,phi+90.,theta,phi);
9065
9066 // Generate smeared position w.r.t. the fictative Z-axis
9067 Double_t pi=acos(-1.);
9068 Double_t cosmax=1;
9069 Double_t cosmin=cos(fabs(sigma)*pi/180.);
9070 Double_t phimin=0;
9071 Double_t phimax=360;
9072 Double_t cost=0;
9073 if (sigma<0)
9074 {
9075 cost=fRan->Uniform(cosmin,cosmax);
9076 theta=acos(cost)*180./pi;
9077 }
9078 else
9079 {
9080 theta=fRan->Gauss(0.,sigma);
9081 }
9082 phi=fRan->Uniform(phimin,phimax);
9083
9084 // Enter the "fake" smeared position into vector "v".
9085 v.SetVector(norm,theta,phi,"sph","deg");
9086
9087 // Invoke the inverse rotation to obtain the actual smeared position.
9088 v=v.GetUnprimed(&m);
9089 if (ier) v.SetErrors(err,"car");
9090}
9091
9093{
9110
9111 if (!v.HasVector()) return;
9112
9113 // If needed, initialise the randomiser with a "date/time driven" seed
9114 // using the timestamp of the moment of this invokation of the member function.
9115 // This will ensure different random sequences if the user repeats analyses
9116 // under identical conditions without explicit initialisation of the randomiser
9117 // by the user at the start of the analysis.
9118 if (!fRan) fRan=new NcRandom(-1);
9119
9120 Double_t norm=v.GetX(1,"sph","deg");
9121 Double_t theta=v.GetX(2,"sph","deg");
9122 Double_t phi=v.GetX(3,"sph","deg");
9123 Double_t err[3]={0,0,0};
9124 Int_t ier=0;
9125 if (v.HasErrors())
9126 {
9127 ier=1;
9128 v.GetErrors(err,"car");
9129 }
9130 if (norm<=0)
9131 {
9132 norm=1;
9133 err[0]=0;
9134 }
9135 v.SetVector(norm,theta,phi,"sph","deg");
9136
9137 // The shifted position will be generated as if the actual vector "v" coincided with the positive Z-axis.
9138 // The actual shifted position will be obtained via a "backward rotation" to the real frame orientation.
9139
9140 // Determine the rotation matrix for the frame in which "v" coincides with the positive Z-axis.
9141 TRotMatrix m;
9142 m.SetAngles(90.+theta,phi,90,phi+90.,theta,phi);
9143
9144 // Generate the shifted position w.r.t. the fictative Z-axis
9145 Double_t phimin=0;
9146 Double_t phimax=360;
9147 theta=angle;
9148 phi=fRan->Uniform(phimin,phimax);
9149
9150 // Enter the "fake" shifted position into vector "v".
9151 v.SetVector(norm,theta,phi,"sph","deg");
9152
9153 // Invoke the inverse rotation to obtain the actual shifted position.
9154 v=v.GetUnprimed(&m);
9155 if (ier) v.SetErrors(err,"car");
9156}
9157
9158TH1F NcAstrolab::GetDxHistogram(TH1* hx,Int_t nc,Double_t dxbin,Double_t dxmin,Double_t dxmax,Int_t mode,Double_t fact)
9159{
9257
9258 TH1F hdx;
9259
9260 if (mode<0 || mode>3) return hdx;
9261
9262 if (!hx) return hdx;
9263
9264 if (nc<1) return hdx;
9265
9266 Int_t nenhx=hx->GetEntries();
9267 if (nenhx<=nc) return hdx;
9268
9269 Int_t idxbin=TMath::Nint(dxbin);
9270 if (idxbin<-2) return hdx;
9271
9272 // Create the output histogram if all parameters have been specified or determined automatically.
9273 // If not, this will be done at a recursive invokation (see below) once (some of) the
9274 // parameters have been determined automatically from the input histogram.
9275 if (dxmin>=0 && dxmax>=dxmin && dxbin>0)
9276 {
9277 Int_t nbins=1;
9278 Double_t range=dxmax-dxmin;
9279 if (range>dxbin) nbins=TMath::Nint(range/dxbin);
9280 hdx.SetBins(nbins,dxmin,dxmax);
9281
9282 // Add histogram and axes titles
9283 TString s;
9284 Double_t binwidth=hdx.GetXaxis()->GetBinWidth(1);
9285 s.Form("Dx interval distribution between %-i consecutive entries (nc=%-i, mode=%-i);Dx interval;Counts per bin of size %-.3g",nc+1,nc,mode,binwidth);
9286 hdx.SetNameTitle("DxHistogram",s);
9287 }
9288
9289 // If needed, initialise the randomiser with a "date/time driven" seed
9290 // using the timestamp of the moment of this invokation of the member function.
9291 // This will ensure different random sequences if the user repeats analyses
9292 // under identical conditions without explicit initialisation of the randomiser
9293 // by the user at the start of the analysis.
9294 if (!fRan) fRan=new NcRandom(-1);
9295
9296 // Determine the minimum and maximum encountered dx or fill the output histogram
9297 Double_t x1,x2,deltax;
9298 Int_t nx1,nx2;
9299 Double_t deltaxmin=0;
9300 Double_t deltaxmax=0;
9301 Bool_t found=kFALSE;
9302 Int_t ndxcount=0;
9303 Int_t jstart;
9304
9305 Int_t nbhx=hx->GetNbinsX();
9306 Double_t value=0;
9307 Double_t xlow=0;
9308 Double_t xup=0;
9309 Double_t bsize=0;
9310 for (Int_t i=1; i<=nbhx; i++)
9311 {
9312 deltax=-1;
9313 ndxcount=0;
9314 xlow=hx->GetBinLowEdge(i);
9315 bsize=hx->GetBinWidth(i);
9316 xup=xlow+bsize;
9317 x1=hx->GetBinCenter(i);
9318 if (mode==1 || mode==3) x1=fRan->Uniform(xlow,xup);
9319 value=hx->GetBinContent(i);
9320 nx1=0;
9321 if (value) nx1=1;
9322 if (mode<2) nx1=TMath::Nint(value);
9323
9324 while (nx1>0)
9325 {
9326 // Check for multiple counts (left) in this bin
9327 jstart=i+1;
9328 if (nx1>1) jstart=i;
9329
9330 for (Int_t j=jstart; j<=nbhx; j++)
9331 {
9332 xlow=hx->GetBinLowEdge(j);
9333 bsize=hx->GetBinWidth(j);
9334 xup=xlow+bsize;
9335 x2=hx->GetBinCenter(j);
9336 if (mode==1 || mode==3) x2=fRan->Uniform(xlow,xup);
9337 value=hx->GetBinContent(j);
9338 nx2=0;
9339 if (value) nx2=1;
9340 if (mode<2) nx2=TMath::Nint(value);
9341
9342 if (j==i) nx2=nx1-1; // Counting within the same bin
9343
9344 // Empty bin
9345 if (nx2<1) continue;
9346
9347 ndxcount+=nx2;
9348
9349 if (ndxcount>=nc)
9350 {
9351 deltax=fabs(x2-x1);
9352 if (dxmin>=0 && dxmax>=dxmin && dxbin>0) // Output histogram has been initialised
9353 {
9354 hdx.Fill(deltax);
9355 }
9356 else // Auto-determination of the output histogram range
9357 {
9358 if (!found || deltax<deltaxmin) deltaxmin=deltax;
9359 if (!found || deltax>deltaxmax) deltaxmax=deltax;
9360 }
9361 ndxcount=0;
9362 found=kTRUE;
9363 break;
9364 }
9365 }
9366 nx1--;
9367 }
9368 }
9369
9370 // Check if a suitable configuration of entries was encountered
9371 if (!found) return hdx;
9372
9373 // Check if a recursive call is needed to actually create and fill the output histogram
9374 Int_t nen=hdx.GetEntries();
9375 if (!nen)
9376 {
9377 // Set the bin size (if needed) for the output histogram
9378 if (!idxbin && dxbin<=0) dxbin=hx->GetBinWidth(1);
9379 if (idxbin==-1)
9380 {
9381 dxbin=(hx->GetBinWidth(1))*fact;
9382 if (deltaxmin>0 && deltaxmin>dxbin) dxbin=deltaxmin;
9383 if (dxbin<=0) dxbin=hx->GetBinWidth(1);
9384 }
9385 if (idxbin==-2)
9386 {
9387 dxbin=hx->GetBinWidth(1);
9388 dxbin=dxbin*float(nc);
9389 }
9390
9391 // Set the auto-determined range of the output histogram
9392 if (dxmin<0)
9393 {
9394 dxmin=deltaxmin;
9395 // Compensate for randomized x-values within the input histogram bins
9396 if (mode==1 || mode==3)
9397 {
9398 bsize=hx->GetBinWidth(1);
9399 dxmin=dxmin-2.*bsize;
9400 if (dxmin<0) dxmin=0;
9401 }
9402 }
9403 if (dxmax<0)
9404 {
9405 dxmax=deltaxmax+dxbin;
9406 // Compensate for randomized x-values within the input histogram bins
9407 if (mode==1 || mode==3)
9408 {
9409 bsize=hx->GetBinWidth(1);
9410 dxmax=dxmax+2.*bsize;
9411 }
9412 }
9413
9414 // Invoke the recursive call to create and fill the output histogram
9415 hdx=GetDxHistogram(hx,nc,dxbin,dxmin,dxmax,mode,fact);
9416 }
9417
9418 return hdx;
9419}
9420
9421TH1F NcAstrolab::GetDifHistogram(TH1* hin,Int_t mode,TString s,TF1* f) const
9422{
9457
9458 TH1F hout;
9459
9460 if (!hin) return hout;
9461
9462 Int_t nbins=hin->GetNbinsX();
9463 if (!nbins) return hout;
9464
9465 // Set the X-axis parameters identical to the input histogram
9466 const TArrayD* xarr=hin->GetXaxis()->GetXbins();
9467 Int_t xsize=xarr->GetSize();
9468 if (!xsize)
9469 {
9470 Double_t xmin=hin->GetXaxis()->GetXmin();
9471 Double_t xmax=hin->GetXaxis()->GetXmax();
9472 hout.SetBins(nbins,xmin,xmax);
9473 }
9474 else
9475 {
9476 const Double_t* xbins=xarr->GetArray();
9477 hout.SetBins(nbins,xbins);
9478 }
9479
9480 // Set histogram title
9481 hout.SetNameTitle("DifHistogram",hin->GetTitle());
9482
9483 // Set axes titles
9484 TString sxin=hin->GetXaxis()->GetTitle();
9485 TString syin=hin->GetYaxis()->GetTitle();
9486
9487 TString sxout=sxin;
9488
9489 TString syout=s;
9490 if (syout=="")
9491 {
9492 if (f)
9493 {
9494 syout=f->GetExpFormula("p");
9495 syout+="*";
9496 }
9497 syout+="d(";
9498 syout+=syin;
9499 syout+=")/d(";
9500
9501 // Remove Log indication from the "hin" X-axis title
9502 // to get a proper dy/dx label for the "hout" Y-axis
9503 if (mode)
9504 {
9505 sxin.ReplaceAll("^{10}log","");
9506 sxin.ReplaceAll("^{10}Log","");
9507 sxin.ReplaceAll("log10","");
9508 sxin.ReplaceAll("Log10","");
9509 sxin.ReplaceAll("log","");
9510 sxin.ReplaceAll("Log","");
9511 sxin.ReplaceAll("ln","");
9512 sxin.ReplaceAll("Ln","");
9513 }
9514
9515 syout+=sxin;
9516 syout+=")";
9517 syout.ReplaceAll("((","(");
9518 syout.ReplaceAll("))",")");
9519 }
9520
9521 hout.GetXaxis()->SetTitle(sxout.Data());
9522 hout.GetYaxis()->SetTitle(syout.Data());
9523
9524 // Determine the new Y-values and fill the output histogram
9525 Double_t x=0;
9526 Double_t y=0;
9527 Double_t err=0;
9528 Double_t width=0;
9529 Double_t binlow=0;
9530 Double_t binup=0;
9531 Double_t scale=0;
9532 for (Int_t i=1; i<=nbins; i++)
9533 {
9534 x=hin->GetBinCenter(i);
9535 y=hin->GetBinContent(i);
9536 err=fabs(hin->GetBinError(i));
9537 width=hin->GetBinWidth(i);
9538 binlow=hin->GetBinLowEdge(i);
9539 binup=binlow+width;
9540
9541 // Check if the binwidth is physical
9542 if (width<=0) continue;
9543
9544 // Correct for log-scale annotation on X-axis
9545 if (mode==1)
9546 {
9547 x=pow(10.,x);
9548 width=pow(10.,binup)-pow(10.,binlow);
9549 }
9550 if (mode==2)
9551 {
9552 x=exp(x);
9553 width=exp(binup)-exp(binlow);
9554 }
9555
9556 y=y/width;
9557 err=err/width;
9558
9559 // Rescale via the function "f" if provided
9560 if (f)
9561 {
9562 scale=f->Eval(x);
9563 y=y*scale;
9564 err=err*scale;
9565 }
9566
9567 hout.SetBinContent(i,y);
9568 hout.SetBinError(i,err);
9569 }
9570
9571 return hout;
9572}
9573
9574TH1F NcAstrolab::GetCountsHistogram(TF1& spec,Int_t nbins,Double_t xmin,Double_t xmax,Int_t mode,TString s) const
9575{
9601
9602 // Setting up the output histogram
9603 TH1F hout;
9604 hout.SetName("CountsHistogram");
9605
9606 // Set histogram title and axes labels
9607 if (s=="")
9608 {
9609 s="CountsHistogram;";
9610 if (mode==1)
9611 {
9612 s+="^{10}Log(";
9613 }
9614 else if (mode==2)
9615 {
9616 s+="Ln(";
9617 }
9618 s+=spec.GetXaxis()->GetTitle();
9619 if (mode) s+=")";
9620 s+=";Counts";
9621 }
9622 hout.SetTitle(s);
9623
9624 // Setting histogram binning
9625 Double_t step=(xmax-xmin)/double(nbins);
9626 Double_t* xbins=new Double_t[nbins+1];
9627 Double_t x=xmin;
9628 for (Int_t ibin=0; ibin<=nbins; ibin++)
9629 {
9630 xbins[ibin]=x;
9631 x=x+step;
9632 }
9633
9634 hout.SetBins(nbins,xbins);
9635
9636 // Filling the output histogram
9637 Double_t xlow=0;
9638 Double_t xup=0;
9639 Double_t N=0;
9640 x=xmin;
9641 for (Int_t ibin=1; ibin<=nbins; ibin++)
9642 {
9643 if (!mode)
9644 {
9645 xlow=xbins[ibin-1];
9646 xup=xbins[ibin];
9647 }
9648 else if (mode==1)
9649 {
9650 xlow=pow(10,xbins[ibin-1]);
9651 xup=pow(10,xbins[ibin]);
9652 }
9653 else if (mode==2)
9654 {
9655 xlow=exp(xbins[ibin-1]);
9656 xup=exp(xbins[ibin]);
9657 }
9658
9659 N=spec.Integral(xlow,xup);
9660 hout.Fill(x,N);
9661 x=x+step;
9662 }
9663
9664 delete [] xbins;
9665
9666 return hout;
9667}
9668
9669TH1F NcAstrolab::GetCountsHistogram(TH1& hin,Int_t mode,TString s,TF1* fscale) const
9670{
9699
9700 // Setting up the output histogram
9701 TH1F hout;
9702 hout.SetName("CountsHistogram");
9703 Int_t nbins=hin.GetNbinsX();
9704
9705 if (nbins<1) return hout;
9706
9707 TAxis* ax=hin.GetXaxis();
9708 Double_t xmin=ax->GetXmin();
9709 Double_t xmax=ax->GetXmax();
9710 hout.SetBins(nbins,xmin,xmax);
9711
9712 // Set histogram title and axes labels
9713 if (s=="")
9714 {
9715 s=hin.GetTitle();
9716 s+=";";
9717 TString tx=ax->GetTitle();
9718 if (tx!="")
9719 {
9720 s+=tx;
9721 }
9722 else
9723 {
9724 if (mode==0) s+="x";
9725 if (mode==1) s+="^{10}Log(x)";
9726 if (mode==2) s+="Ln(x)";
9727 }
9728 s+=";Counts";
9729 }
9730 hout.SetTitle(s);
9731
9732 // Filling the output histogram
9733 Double_t x=0;
9734 Double_t xlow=0;
9735 Double_t xup=0;
9736 Double_t dx=0;
9737 Double_t xval=0;
9738 Double_t N=0;
9739 Double_t fval=0;
9740 for (Int_t ibin=1; ibin<=nbins; ibin++)
9741 {
9742 x=hin.GetBinCenter(ibin);
9743 xlow=hin.GetBinLowEdge(ibin);
9744 xup=xlow+hin.GetBinWidth(ibin);
9745 N=hin.GetBinContent(ibin);
9746 if (!mode)
9747 {
9748 xval=x;
9749 dx=xup-xlow;
9750 N=N*dx;
9751 }
9752 else if (mode==1)
9753 {
9754 xval=pow(10,x);
9755 dx=pow(10,xup)-pow(10,xlow);
9756 N=N*dx;
9757 }
9758 else if (mode==2)
9759 {
9760 xval=exp(x);
9761 dx=exp(xup)-exp(xlow);
9762 N=N*dx;
9763 }
9764
9765 // Compensate for the Y-axis scaling if needed
9766 if (fscale)
9767 {
9768 fval=fscale->Eval(xval);
9769 if (fval) N=N/fval;
9770 }
9771
9772 hout.Fill(x,N);
9773 }
9774
9775 return hout;
9776}
9777
9778TH1F NcAstrolab::GetLogHistogram(TH1* hin,Int_t mode,TString s) const
9779{
9799
9800 TH1F hout;
9801
9802 if (!hin || mode<1 || mode>2) return hout;
9803
9804 Int_t nbins=hin->GetNbinsX();
9805 if (!nbins) return hout;
9806
9807 // Set the X-axis parameters identical to the input histogram
9808 const TArrayD* xarr=hin->GetXaxis()->GetXbins();
9809 Int_t xsize=xarr->GetSize();
9810 if (!xsize)
9811 {
9812 Double_t xmin=hin->GetXaxis()->GetXmin();
9813 Double_t xmax=hin->GetXaxis()->GetXmax();
9814 hout.SetBins(nbins,xmin,xmax);
9815 }
9816 else
9817 {
9818 const Double_t* xbins=xarr->GetArray();
9819 hout.SetBins(nbins,xbins);
9820 }
9821
9822 // Set histogram and axes titles
9823 hout.SetNameTitle("LogHistogram",hin->GetTitle());
9824
9825 if (s=="")
9826 {
9827 s="^{10}Log(";
9828 if (mode==2) s="Ln(";
9829 s+=hin->GetYaxis()->GetTitle();
9830 s+=")";
9831 }
9832
9833 hout.GetXaxis()->SetTitle(hin->GetXaxis()->GetTitle());
9834 hout.GetYaxis()->SetTitle(s.Data());
9835
9836 // Determine the new Y-values and fill the output histogram
9837 Double_t y=0;
9838 Double_t err=0;
9839 Double_t yplus=0;
9840 for (Int_t i=1; i<=nbins; i++)
9841 {
9842 y=hin->GetBinContent(i);
9843 err=fabs(hin->GetBinError(i));
9844 yplus=y+err;
9845
9846 // Check if Log10(y) or Ln(y) is defined
9847 if (y<=0) continue;
9848
9849 if (mode==1)
9850 {
9851 y=log10(y);
9852 yplus=log10(yplus);
9853 }
9854 else
9855 {
9856 y=log(y);
9857 yplus=log(yplus);
9858 }
9859
9860 hout.SetBinContent(i,y);
9861 err=fabs(yplus-y);
9862 hout.SetBinError(i,err);
9863 }
9864
9865 return hout;
9866}
9867
9868Double_t NcAstrolab::GetBackgroundRateProb(Double_t* vars,Double_t* pars)
9869{
9901
9902 Double_t b=vars[0];
9903 Int_t Noff=int(pars[0]);
9904 Double_t Toff=pars[1];
9905 Double_t bmax=pars[2];
9906 Double_t prec=pars[3];
9907
9908 if (b<=0 || Noff<0 || Toff<=0) return 0;
9909
9910 Double_t rNoff=Noff;
9911 if (bmax<0) bmax=100.*rNoff/Toff;
9912
9913 NcMath math;
9914
9915 Double_t lnU=0;
9916 Double_t lnD=0;
9917 Double_t lnprob=0;
9918 Double_t prob=0;
9919
9920 // The ln of the numerator of Eq.(15) of the publication mentioned above
9921 lnU=log(Toff)+rNoff*log(b*Toff)-b*Toff;
9922
9923 // The ln of the denominator of eq.(15) of the publication mentioned above
9924 lnD=math.LnGamma(Noff+1,bmax*Toff,1);
9925
9926 lnprob=lnU-lnD;
9927
9928 if (lnprob < -fabs(prec)) return 0;
9929
9930 if (lnprob > fabs(prec)) lnprob=fabs(prec);
9931 prob=exp(lnprob);
9932
9933 return prob;
9934}
9935
9936Double_t NcAstrolab::GetSignalRateProb(Double_t* vars,Double_t* pars)
9937{
9980
9981 Double_t s=vars[0];
9982 Int_t Non=TMath::Nint(pars[0]);
9983 Double_t Ton=pars[1];
9984 Int_t Noff=TMath::Nint(pars[2]);
9985 Double_t Toff=pars[3];
9986 Double_t smax=pars[4];
9987 Double_t bmax=pars[5];
9988 Double_t prec=pars[6];
9989
9990 if (s<0 || Non<0 || Ton<=0 || Noff<0 || Toff<=0) return 0;
9991
9992 Double_t rNon=Non;
9993 if (smax<0) smax=100.*rNon/Ton;
9994
9995 Double_t rNoff=Noff;
9996 if (bmax<0) bmax=100.*rNoff/Toff;
9997
9998 NcMath math;
9999
10000 //Store factorials in an array to decrease the processing time
10001 Int_t ndim=Non+Noff+1;
10002 TArrayD lnfacN(ndim);
10003
10004 lnfacN[0]=0;
10005 Double_t x=0;
10006 for (Int_t i=1; i<ndim; i++)
10007 {
10008 x+=log(double(i));
10009 lnfacN[i]=x;
10010 }
10011
10012 Double_t lnU=0;
10013 Double_t lnD=0;
10014 Double_t sumU=0;
10015 Double_t sumD=0;
10016 Double_t prob=0;
10017 Double_t gammaP1=0;
10018 Double_t gammaP2=0;
10019 Double_t ri=0;
10020
10021 for(Int_t i=0; i<=Non; i++)
10022 {
10023 ri=i;
10024
10025 // The incomplete gamma functions P(a,x)
10026 gammaP1=math.Gamma(Non+Noff+1-i,bmax*(Ton+Toff),0);
10027 gammaP2=math.Gamma(i+1,smax*Ton,0);
10028
10029 // The ln of the numerator of Eq.(21) of the publication mentioned above normalized by Non!/(Non+Noff)!
10030 lnU=-s*Ton+ri*log(s)+ri*log(Ton+Toff)-lnfacN[i]-lnfacN[Non-i]+lnfacN[Non+Noff-i]-lnfacN[Non+Noff]+lnfacN[Non];
10031
10032 if ((lnU > -fabs(prec)) && (lnU < fabs(prec))) sumU+=exp(lnU)*gammaP1;
10033
10034 //The ln of the denominator of Eq.(21) of the publication mentioned above normalized by Non!/(Non+Noff)!
10035 lnD=ri*log(Ton+Toff)-(ri+1.)*log(Ton)-lnfacN[i]-lnfacN[Non-i]+lnfacN[Non+Noff-i]+lnfacN[i]-lnfacN[Non+Noff]+lnfacN[Non];
10036
10037 if ((lnD > -fabs(prec)) && (lnD < fabs(prec))) sumD+=exp(lnD)*gammaP1*gammaP2;
10038 }
10039
10040 if (sumD) prob=sumU/sumD;
10041
10042 return prob;
10043}
10044
10045TF1 NcAstrolab::GetBackgroundRatePDF(Double_t Noff,Double_t Toff,Double_t bmax,Double_t prec)
10046{
10076
10077 if (bmax<0) bmax=100.*Noff/Toff;
10078
10079 Int_t npar=4;
10080 TF1 pdf("BkgRatePDF",this,&NcAstrolab::GetBackgroundRateProb,0,bmax,npar);
10081
10082 pdf.SetParName(0,"Noff");
10083 pdf.SetParName(1,"Toff");
10084 pdf.SetParName(2,"bmax");
10085 pdf.SetParName(3,"prec");
10086
10087 pdf.SetParameter("Noff",Noff);
10088 pdf.SetParameter("Toff",Toff);
10089 pdf.SetParameter("bmax",bmax);
10090 pdf.SetParameter("prec",prec);
10091
10092 pdf.SetTitle("Bayesian posterior background rate PDF;Background rate B in Hz;p(B|Noff,Toff,I)");
10093 pdf.SetRange(0,bmax);
10094
10095 return pdf;
10096}
10097
10098TF1 NcAstrolab::GetSignalRatePDF(Double_t Non,Double_t Ton,Double_t Noff,Double_t Toff,Double_t Ra,Double_t Re,Double_t smax,Double_t bmax,Double_t prec)
10099{
10137
10138 if (smax<0) smax=100.*Non/Ton;
10139
10140 // Correct the off source observation for different coverage and detection efficiency
10141 // with respect to the actual on source measurement
10142 Noff=Noff*Ra*Re;
10143
10144 if (bmax<0) bmax=100.*Noff/Toff;
10145
10146 Int_t npar=7;
10147 TF1 pdf("SignalRatePDF",this,&NcAstrolab::GetSignalRateProb,0,smax,npar);
10148
10149 pdf.SetParName(0,"Non");
10150 pdf.SetParName(1,"Ton");
10151 pdf.SetParName(2,"Noff");
10152 pdf.SetParName(3,"Toff");
10153 pdf.SetParName(4,"smax");
10154 pdf.SetParName(5,"bmax");
10155 pdf.SetParName(6,"prec");
10156
10157 pdf.SetParameter("Non",Non);
10158 pdf.SetParameter("Ton",Ton);
10159 pdf.SetParameter("Noff",Noff);
10160 pdf.SetParameter("Toff",Toff);
10161 pdf.SetParameter("smax",smax);
10162 pdf.SetParameter("bmax",bmax);
10163 pdf.SetParameter("prec",prec);
10164
10165 pdf.SetTitle("Bayesian posterior signal rate PDF;Signal rate S in Hz;p(S|Non,Ton,Noff,Toff,I)");
10166 pdf.SetRange(0,smax);
10167
10168 return pdf;
10169}
10170
10171Double_t NcAstrolab::GetUpperLimit(TF1 pdf,Double_t p)
10172{
10189
10190 if (p<=0 || p>100) return 0;
10191
10192 Double_t ua[2];
10193 Double_t xa[2];
10194 Int_t nu=0;
10195 Double_t ul=0;
10196
10197 xa[0]=p/100.;
10198 nu=pdf.GetQuantiles(1,ua,xa);
10199
10200 if (nu) ul=ua[0];
10201
10202 return ul;
10203}
10204
10205Double_t NcAstrolab::GetUpperLimit(TH1* his,Double_t p)
10206{
10216
10217 if (p<=0 || p>100 || !his) return 0;
10218
10219 Double_t ua[2];
10220 Double_t xa[2];
10221 Int_t nu=0;
10222 Double_t ul=0;
10223
10224 // Ensure correct results als for histograms filled via SetBinContent().
10225 his->ComputeIntegral();
10226
10227 xa[0]=p/100.;
10228 nu=his->GetQuantiles(1,ua,xa);
10229
10230 if (nu) ul=ua[0];
10231
10232 return ul;
10233}
10234
10235Double_t NcAstrolab::GetCredibleInterval(TF1 pdf,Double_t p,Double_t& xlow,Double_t& xup,Int_t n)
10236{
10268
10269 xlow=0;
10270 xup=0;
10271
10272 if (p<=0 || p>100 || n<2) return 0;
10273
10274 // Set the precision
10275 Double_t prec=1./double(n);
10276
10277 // Obtain the n quantiles of the PDF
10278 Double_t* q=new Double_t[n];
10279 Double_t* sumq=new Double_t[n];
10280 Double_t sum=0;
10281 for (Int_t i=0; i<n; i++)
10282 {
10283 sumq[i]=sum;
10284 sum+=prec;
10285 }
10286 Int_t ncalc=pdf.GetQuantiles(n,q,sumq);
10287
10288 // More than 1 quantile is needed
10289 if (ncalc<2)
10290 {
10291 delete [] q;
10292 delete [] sumq;
10293 return 0;
10294 }
10295
10296 // Determine the index in the quantiles array q[] corresponding to
10297 // the X coordinate of the mode of the PDF
10298 Double_t xmode=pdf.GetMaximumX();
10299 Int_t imode=0;
10300 Double_t diff,diffmin;
10301 diffmin=fabs(q[ncalc-1]-q[0]);
10302 for (Int_t i=0; i<ncalc; i++)
10303 {
10304 diff=fabs(xmode-q[i]);
10305 if (diff<diffmin)
10306 {
10307 diffmin=diff;
10308 imode=i;
10309 }
10310 }
10311
10312 // Get the total integral over the quantiles range of the PDF
10313 Double_t xmin=q[0];
10314 Double_t xmax=q[ncalc-1];
10315 Double_t totint=pdf.Integral(xmin,xmax);
10316
10317 // The PDF should have a total integral >0
10318 if (totint<=0)
10319 {
10320 delete [] q;
10321 delete [] sumq;
10322 return 0;
10323 }
10324
10325 // Determine the requested credible interval around the mode
10326 Int_t ilow=imode;
10327 Int_t iup=imode;
10328 xlow=q[ilow];
10329 xup=q[iup];
10330 Double_t ylow=pdf.Eval(q[ilow]);
10331 Double_t yup=pdf.Eval(q[iup]);
10332 Double_t frac=p/100.;
10333 if (frac>1) frac=1;
10334 Double_t credint=-1;
10335 while (credint<frac*totint)
10336 {
10337 if (yup>ylow && iup<(ncalc-1)) // Shift the upper bound up
10338 {
10339 iup++;
10340 xup=q[iup];
10341 yup=pdf.Eval(xup);
10342 }
10343 else if (ylow>yup && ilow>0) // Shift the lower bound down
10344 {
10345 ilow--;
10346 xlow=q[ilow];
10347 ylow=pdf.Eval(xlow);
10348 }
10349 else if (iup<(ncalc-1)) // Shift the upper bound up in case yup=ylow
10350 {
10351 iup++;
10352 xup=q[iup];
10353 yup=pdf.Eval(xup);
10354 }
10355 else if (ilow>0) // Shift the lower bound down in case yup=ylow
10356 {
10357 ilow--;
10358 xlow=q[ilow];
10359 ylow=pdf.Eval(xlow);
10360 }
10361 else // No shift in any bound -> stop
10362 {
10363 break;
10364 }
10365 credint=pdf.Integral(xlow,xup);
10366 }
10367
10368 // Normalisation for non-normalised PDF
10369 Double_t intfrac=credint/totint;
10370
10371 delete [] q;
10372 delete [] sumq;
10373
10374 return intfrac;
10375}
10376
10377Double_t NcAstrolab::GetCredibleInterval(TF1 pdf,Double_t p,Float_t& xlow,Float_t& xup,Int_t n)
10378{
10410
10411 Double_t xxl=0;
10412 Double_t xxu=0;
10413 Double_t val=0;
10414
10415 val=GetCredibleInterval(pdf,p,xxl,xxu,n);
10416
10417 xlow=xxl;
10418 xup=xxu;
10419 return val;
10420}
10421
10422Double_t NcAstrolab::GetCredibleInterval(TH1* his,Double_t p,Double_t& xlow,Double_t& xup)
10423{
10445
10446 xlow=0;
10447 xup=0;
10448
10449 if (p<=0 || p>100 || !his) return 0;
10450
10451 Int_t nbins=his->GetNbinsX();
10452
10453 // More than 2 bins are always needed
10454 if (nbins<2) return 0;
10455
10456 // Ensure correct results also for histograms filled via SetBinContent()
10457 his->ComputeIntegral();
10458
10459 // Obtain the quantiles at the end of each bin of the histogram and at the start of the 1st bin
10460 Int_t n=nbins+1;
10461 Double_t* q=new Double_t[n];
10462 Int_t ncalc=his->GetQuantiles(n,q);
10463
10464 // More than 1 quantile is needed
10465 if (ncalc<2)
10466 {
10467 delete [] q;
10468 return 0;
10469 }
10470
10471 // Determine the index in the quantiles array q[] corresponding to
10472 // the X coordinate of the mode of the histogram
10473 Int_t imode=his->GetMaximumBin();
10474
10475 // Get the total integral of the histogram over the quantiles range
10476 Double_t totint=his->Integral(1,ncalc,"width");
10477
10478 // The histogram should have a total integral >0
10479 if (totint<=0)
10480 {
10481 delete [] q;
10482 return 0;
10483 }
10484
10485 // Determine the requested credible interval around the mode
10486 Int_t ilow=imode;
10487 Int_t iup=imode;
10488 xlow=q[ilow];
10489 xup=q[iup];
10490 Double_t ylow=his->GetBinContent(ilow);
10491 Double_t yup=his->GetBinContent(iup);
10492 Double_t frac=p/100.;
10493 if (frac>1) frac=1;
10494 Double_t credint=-1;
10495 while (credint<frac*totint)
10496 {
10497 if (yup>ylow && iup<(ncalc-1)) // Shift the upper bound up
10498 {
10499 iup++;
10500 xup=q[iup];
10501 yup=his->GetBinContent(iup);
10502 }
10503 else if (ylow>yup && ilow>0) // Shift the lower bound down
10504 {
10505 ilow--;
10506 xlow=q[ilow];
10507 ylow=his->GetBinContent(ilow);
10508 }
10509 else if (iup<(ncalc-1)) // Shift the upper bound up in case yup=ylow
10510 {
10511 iup++;
10512 xup=q[iup];
10513 yup=his->GetBinContent(iup);
10514 }
10515 else if (ilow>0) // Shift the lower bound down in case yup=ylow
10516 {
10517 ilow--;
10518 xlow=q[ilow];
10519 ylow=his->GetBinContent(ilow);
10520 }
10521 else // No shift in any bound -> stop
10522 {
10523 break;
10524 }
10525 credint=his->Integral(ilow,iup,"width");
10526 }
10527
10528 // Normalisation for non-normalised PDF
10529 Double_t intfrac=credint/totint;
10530
10531 delete [] q;
10532
10533 return intfrac;
10534}
10535
10536Double_t NcAstrolab::GetCredibleInterval(TH1* his,Double_t p,Float_t& xlow,Float_t& xup)
10537{
10559
10560 Double_t xxl=0;
10561 Double_t xxu=0;
10562 Double_t val=0;
10563
10564 val=GetCredibleInterval(his,p,xxl,xxu);
10565
10566 xlow=xxl;
10567 xup=xxu;
10568 return val;
10569}
10570
10571Double_t NcAstrolab::KolmogorovTest(TString mode,TH1* h1,TH1* h2,TF1* pdf,Double_t nr,TH1F* ksh,Int_t ncut,Double_t* nrx,Int_t mark)
10572{
10665
10666 Double_t value=-1;
10667
10668 if (!mode.Contains("M") && !mode.Contains("K") && !mode.Contains("P")) return -1;
10669 if (mode.Contains("M") && (mode.Contains("K") || mode.Contains("P"))) return -1;
10670 if (mode.Contains("K") && (mode.Contains("M") || mode.Contains("P"))) return -1;
10671 if (mode.Contains("P") && (mode.Contains("M") || mode.Contains("K"))) return -1;
10672
10673 if (!h1) return -1;
10674 if (!h2 && !pdf) return -1;
10675 if (h2 && pdf) return -1;
10676
10677 ULong64_t nrep=ULong64_t(nr);
10678 ULong64_t jrep;
10679 if (!nrep)
10680 {
10681 if (ncut)
10682 {
10683 nrep=ULong64_t(1.e19);
10684 }
10685 else
10686 {
10687 return -1;
10688 }
10689 }
10690
10691 TAxis* xaxis=h1->GetXaxis();
10692 Double_t xmin1=xaxis->GetXmin();
10693 Double_t xmax1=xaxis->GetXmax();
10694 Double_t range1=xmax1-xmin1;
10695 Int_t nbins1=h1->GetNbinsX();
10696 Double_t nen1=h1->GetSumOfWeights();
10697 Double_t underflow1=h1->GetBinContent(0);
10698 Double_t overflow1=h1->GetBinContent(nbins1+1);
10699 if (mode.Contains("U")) nen1=nen1+underflow1;
10700 if (mode.Contains("O")) nen1=nen1+overflow1;
10701
10702 if (nbins1<=0 || nen1<=0 || range1<=0)
10703 {
10704 cout << " *" << ClassName() << "::KolmogorovTest* Histogram h1 is empty or has inconsistent data." << endl;
10705 cout << " h1 : nentries=" << nen1 << " nbins=" << nbins1 << " xmin=" << xmin1 << " xmax=" << xmax1 << endl;
10706 return -1;
10707 }
10708
10709 if (h2)
10710 {
10711 xaxis=h2->GetXaxis();
10712 Double_t xmin2=xaxis->GetXmin();
10713 Double_t xmax2=xaxis->GetXmax();
10714 Double_t range2=xmax2-xmin2;
10715 Int_t nbins2=h2->GetNbinsX();
10716 Double_t nen2=h2->GetSumOfWeights();
10717
10718 if (nen2<=0 || range2<=0)
10719 {
10720 cout << " *" << ClassName() << "::KolmogorovTest* Histogram h2 is empty or has inconsistent data." << endl;
10721 cout << " h2 : nentries=" << nen2 << " nbins=" << nbins2 << " xmin=" << xmin2 << " xmax=" << xmax2 << endl;
10722 return -1;
10723 }
10724
10725 Double_t prec=1e-6;
10726 if (nbins2!=nbins1 || fabs(xmin2-xmin1)>prec || fabs(xmax2-xmax1)>prec)
10727 {
10728 cout << " *" << ClassName() << "::KolmogorovTest* Histograms h1 and h2 do not have the same binning." << endl;
10729 cout << " h1 : nbins=" << nbins1 << " xmin=" << xmin1 << " xmax=" << xmax1 << endl;
10730 cout << " h2 : nbins=" << nbins2 << " xmin=" << xmin2 << " xmax=" << xmax2 << endl;
10731 return -1;
10732 }
10733 }
10734
10735 // Create the "h2" histogram from the "pdf" function to perform the KS test
10736 if (pdf)
10737 {
10738 pdf->SetRange(xmin1,xmax1);
10739 pdf->SetNpx(nbins1);
10740 h2=(TH1*)pdf->GetHistogram()->Clone();
10741 h2->SetName("hpdf");
10742 // Set all bin errors (incl. underflow and overflow bins) to zero
10743 for (Int_t i=0; i<=nbins1+1; i++)
10744 {
10745 h2->SetBinError(i,0);
10746 }
10747 }
10748
10749 // Convert "mode" into the corresponding character string for TH1::KolmogorovTest
10750 TString s="";
10751 if (mode.Contains("U")) s+="U";
10752 if (mode.Contains("O")) s+="O";
10753 if (mode.Contains("N") && !pdf) s+="N";
10754
10755 // Obtain the maximum KS distance (d0) for the input histogram "h1"
10756 TString s2=s;
10757 s2+="M";
10758 Double_t d0=h2->KolmogorovTest(h1,s2.Data());
10759
10760 // Complete "mode" conversion
10761 if (mode.Contains("M")) s+="M";
10762 if (mode.Contains("I")) s+="D";
10763
10764 // Perform the requested KS test
10765 if (mode.Contains("I"))
10766 {
10767 if (pdf)
10768 {
10769 cout << " *" << ClassName() << "::KolmogorovTest* Single sample KS-test results for execution mode "<< mode.Data() << endl;
10770 if (mode.Contains("N")) cout << " === For a single sample KS-test the mode=N is suppressed ===" << endl;
10771 }
10772 else
10773 {
10774 cout << " *" << ClassName() << "::KolmogorovTest* Two sample KS-test results for execution mode "<< mode.Data() << endl;
10775 }
10776 }
10777 value=h1->KolmogorovTest(h2,s.Data());
10778
10779 // Perform the pseudo experiments, if requested
10780 if (ksh) ksh->SetBins(101,0,1.01);
10781 Double_t xval=0;
10782 Double_t dist=0;
10783 Double_t sumrep=0;
10784 Int_t sumd=0;
10785 TH1* htemp=0;
10786 if (mode.Contains("P"))
10787 {
10788 htemp=(TH1*)h1->Clone();
10789 for (jrep=0; jrep<nrep; jrep++) // Loop of pseudo experiments
10790 {
10791 htemp->Reset();
10792 for (Int_t ien=0; ien<nen1; ien++) // Take the random entries from the reference distribution
10793 {
10794 xval=h2->GetRandom();
10795 htemp->Fill(xval);
10796 }
10797 dist=htemp->KolmogorovTest(h2,s2.Data());
10798 if (ksh) ksh->Fill(dist);
10799 sumrep+=1;
10800 if (dist>=d0) sumd++;
10801
10802 // Stop the pseudo experiments if the required precision is reached
10803 if (ncut && sumd>=ncut) break;
10804
10805 } // end loop over pseudo experiments
10806 value=double(sumd)/sumrep;
10807 if (nrx) *nrx=sumrep;
10808 if (mode.Contains("I"))
10809 {
10810 cout << " P-value = " << value << " after " << sumrep << " pseudo experiments." << endl;
10811 }
10812 }
10813
10814 if (mode.Contains("I")) cout << " Returned value = " << value << endl;
10815
10816 // Complete the attributes for the "ksh" histogram
10817 if (ksh)
10818 {
10819 TString xlabel="Dmax";
10820 TString ylabel="Counts after ";
10821 ylabel+=sumrep;
10822 ylabel+=" pseudo experiments";
10823
10824 ksh->SetTitle("KS-test Dmax distribution from pseudo experiments");
10825 ksh->SetXTitle(xlabel.Data());
10826 ksh->SetYTitle(ylabel.Data());
10827
10828 // Mark the actually observed D0 value by a vertical line in the "ksh" histogram
10829 // Also the corresponding P-value is mentioned in the legend
10830 if (mark)
10831 {
10832 Float_t x=d0;
10833 Float_t ymin=0;
10834 Float_t ymax=ksh->GetMaximum();
10835
10836 TLine* vline=new TLine(x,ymin,x,ymax);
10837 vline->SetLineStyle(2); // Dashed line
10838 vline->SetLineWidth(2);
10839 vline->SetLineColor(4); // Blue color
10840
10841 TString title="P-value : %-10.3g";
10842 TString sh=title.Format(title.Data(),value);
10843
10844 TLegend* leg=new TLegend(0.6,0.8,0.8,0.9);
10845 leg->SetFillColor(0);
10846 leg->SetHeader(sh.Data());
10847 leg->AddEntry(vline,"Observed Dmax","L");
10848
10849 TList* hlist=ksh->GetListOfFunctions();
10850 hlist->Add(vline);
10851 hlist->Add(leg);
10852 }
10853 }
10854
10855 // Delete temporary histograms, if any
10856 if (pdf && h2)
10857 {
10858 delete h2;
10859 h2=0;
10860 }
10861
10862 if (htemp) delete htemp;
10863
10864 return value;
10865}
10866
10867TH1F NcAstrolab::GetCumulHistogram(TH1* h,TString name,TString mode) const
10868{
10895
10896 TH1F hcd;
10897 TString title="Cumulative Distribution of histogram ";
10898 hcd.SetNameTitle(name.Data(),title.Data());
10899
10900 if (!h) return hcd;
10901
10902 TAxis* xaxis=h->GetXaxis();
10903 TAxis* yaxis=h->GetYaxis();
10904 Double_t xmin=xaxis->GetXmin();
10905 Double_t xmax=xaxis->GetXmax();
10906 Double_t range=xmax-xmin;
10907 Int_t nbins=h->GetNbinsX();
10908 Double_t nen=h->GetSumOfWeights();
10909 TString nameh=h->GetName();
10910 TString xtitle=xaxis->GetTitle();
10911 TString ytitle=yaxis->GetTitle();
10912 title+=nameh;
10913 hcd.SetNameTitle(name.Data(),title.Data());
10914 hcd.SetXTitle(xtitle.Data());
10915 hcd.SetYTitle(ytitle.Data());
10916
10917 if (nbins<=0 || nen<=0 || range<=0) return hcd;
10918
10919 if(!(mode.Contains("F") || mode.Contains("B")) || (mode.Contains("F") && mode.Contains("B"))) return hcd;
10920
10921 hcd.SetBins(nbins,xmin,xmax);
10922 title="";
10923 if (mode.Contains("N")) title="Normalized ";
10924 if (mode.Contains("F")) title+="Forward ";
10925 if (mode.Contains("B")) title+="Backward ";
10926 title+="Cumulative Distribution of histogram ";
10927 title+=nameh;
10928 hcd.SetNameTitle(name.Data(),title.Data());
10929 hcd.SetXTitle(xtitle.Data());
10930 hcd.SetYTitle(ytitle.Data());
10931
10932 Double_t norm=1;
10933 if (mode.Contains("N")) norm=nen;
10934 Double_t y=0;
10935 Double_t sum=0;
10936
10937 if (mode.Contains("F")) // Forward cumulation
10938 {
10939 for (Int_t ibin=1; ibin<=nbins; ibin++)
10940 {
10941 y=h->GetBinContent(ibin);
10942 sum+=y/norm;
10943 hcd.SetBinContent(ibin,sum);
10944 }
10945 }
10946 else // Backward cumulation
10947 {
10948 for (Int_t ibin=nbins; ibin>=1; ibin--)
10949 {
10950 y=h->GetBinContent(ibin);
10951 sum+=y/norm;
10952 hcd.SetBinContent(ibin,sum);
10953 }
10954 }
10955 return hcd;
10956}
10957
10958TH1F NcAstrolab::GetCumulHistogram(TF1* f,TString name,Int_t nbins,Double_t xmin,Double_t xmax,TString mode) const
10959{
10987
10988 TH1F hcd;
10989 TString title="Cumulative Distribution Histogram of function ";
10990 hcd.SetNameTitle(name.Data(),title.Data());
10991
10992 if (!f) return hcd;
10993
10994 // The original range of the function "f"
10995 Double_t xminold=f->GetXmin();
10996 Double_t xmaxold=f->GetXmax();
10997
10998 f->SetRange(xmin,xmax);
10999 f->SetNpx(nbins);
11000 TH1* hf=(TH1*)f->GetHistogram();
11001
11002 hcd=GetCumulHistogram(hf,name,mode);
11003
11004 if (hcd.GetEntries()>0) // Histogram has been filled
11005 {
11006 title="";
11007 if (mode.Contains("N")) title="Normalized ";
11008 if (mode.Contains("F")) title+="Forward ";
11009 if (mode.Contains("B")) title+="Backward ";
11010 title+="Cumulative Distribution Histogram of function ";
11011 }
11012
11013 TString namef=f->GetName();
11014 title+=namef;
11015
11016 hcd.SetTitle(title.Data());
11017
11018 // Restore the original range for the function "f"
11019 f->SetRange(xminold,xmaxold);
11020
11021 return hcd;
11022}
11023
11024void NcAstrolab::InitDataNames(Int_t dir,TString frame,TString mode)
11025{
11052
11053 if (!dir || (frame!="equ" && frame!="gal" && frame!="ecl" && frame!="hor" && frame!="icr" && frame!="loc") ||
11054 (mode!="M" && mode!="T" && mode!="B" && mode!="J"))
11055 {
11056 cout << endl;
11057 cout << " *" << ClassName() << "::InitDataNames* Invalid input encountered." << endl;
11058 cout << " dir=" << dir << " frame=" << frame << " mode=" << mode << endl;
11059 return;
11060 }
11061
11062 fDataDir=dir;
11063 fDataFrame=frame;
11064 fDataMode=mode;
11065
11066 // Reset the correspondence table
11067 fDataNames.Reset();
11068
11069 TString sdir="arrival";
11070 if (dir<0) sdir="moving";
11071
11072 if (frame=="equ")
11073 {
11074 if (mode=="M") frame="mean";
11075 if (mode=="T") frame="true";
11076 if (mode=="B") frame="B1950";
11077 if (mode=="J") frame="J2000";
11078 frame+=" equatorial";
11079 }
11080 if (frame=="gal") frame="galactic";
11081 if (frame=="ecl") frame="ecliptic";
11082 if (frame=="hor") frame="horizontal";
11083 if (frame=="icr") frame="ICRS";
11084 if (frame=="loc") frame="local";
11085
11086 cout << endl;
11087 cout << " *" << ClassName() << "::InitDataNames* Prepared for input of " << sdir << " directions in " << frame << " coordinates." << endl;
11088 cout << endl;
11089}
11090
11091void NcAstrolab::SetDataNames(TString obsname,TString varname,TString units,TString func)
11092{
11179
11180 Bool_t error=kFALSE;
11181
11182 if (obsname!="Name" && obsname!="Run" && obsname!="Event" && obsname!="Eventb" && obsname!="VetoLevel"
11183 && obsname!="DetId" && obsname!="Date" && obsname!="Tobs" && obsname!="Tstart" && obsname!="Tend"
11184 && obsname!="d" && obsname!="a" && obsname!="b" && obsname!="z"
11185 && obsname!="E" && obsname!="L" && obsname!="S" && obsname!="F" && obsname!="I" && obsname!="J"
11186 && obsname!="T90" && obsname!="T100"
11187 && obsname!="dsigma" && obsname!="csigma" && obsname!="zsigma"
11188 && obsname!="Esigma" && obsname!="Lsigma" && obsname!="Ssigma" && obsname!="Fsigma" && obsname!="Isigma"
11189 && obsname!="T90sigma" && obsname!="T100sigma") error=kTRUE;
11190 if (obsname=="Date" && (units!="ddmmyyyy" && units!="yyyymmdd" && units!="mmddyyyy" && units!="yyyyddmm")) error=kTRUE;
11191 if ((obsname=="Tobs" || obsname=="Tstart" || obsname=="Tend")
11192 && (units!="JD" && units!="MJD" && units!="TJD" && units!="hms" && units!="hrs")) error=kTRUE;
11193 if ((obsname=="a" || obsname=="b" || obsname=="csigma")
11194 && (units!="rad" && units!="deg" && units!="dms" && units!="hms" && units!="hrs")) error=kTRUE;
11195 if (func!="none" && func!="Log" && func!="Ln") error=kTRUE;
11196
11197 if (error)
11198 {
11199 cout << " *" << ClassName() << "::SetDataNames* Invalid input encountered." << endl;
11200 cout << " obsname=" << obsname << " units=" << units << " func=" << func << endl;
11201 return;
11202 }
11203
11204 Int_t n=fDataNames.GetMaxRow();
11205 TObjString* obs=new TObjString(obsname);
11206 TObjString* var=new TObjString(varname);
11207 TObjString* u=new TObjString(units);
11208 TObjString* f=new TObjString(func);
11209 TObjString* val=new TObjString(""); // Value will be filled in LoadInputData()
11210
11211 fDataNames.EnterObject(n+1,1,obs);
11212 fDataNames.EnterObject(n+1,2,var);
11213 fDataNames.EnterObject(n+1,3,u);
11214 fDataNames.EnterObject(n+1,4,f);
11215 fDataNames.EnterObject(n+1,5,val);
11216}
11217
11219{
11226
11227 TString sdir="undefined";
11228 if (fDataDir>0) sdir="arrival";
11229 if (fDataDir<0) sdir="moving";
11230
11231 TString frame="undefined";
11232 if (fDataFrame=="equ")
11233 {
11234 if (fDataMode=="M") frame="mean";
11235 if (fDataMode=="T") frame="true";
11236 if (fDataMode=="B") frame="B1950";
11237 if (fDataMode=="J") frame="J2000";
11238 frame+=" equatorial";
11239 }
11240 if (fDataFrame=="gal") frame="galactic";
11241 if (fDataFrame=="ecl") frame="ecliptic";
11242 if (fDataFrame=="hor") frame="horizontal";
11243 if (fDataFrame=="icr") frame="ICRS";
11244 if (fDataFrame=="loc") frame="local";
11245
11246 cout << endl;
11247 cout << " *" << ClassName() << "::ListDataNames* Settings for input of " << sdir << " directions in " << frame << " coordinates." << endl;
11248
11249 Int_t n=fDataNames.GetMaxRow();
11250
11251 if (n<1)
11252 {
11253 cout << " *** No settings were specified ***" << endl;
11254 }
11255 else
11256 {
11257 cout << " *** The following " << n << " settings were specified ***" << endl;
11258 }
11259
11260 TObjString* obs=0;
11261 TObjString* var=0;
11262 TObjString* u=0;
11263 TObjString* f=0;
11264 for (Int_t i=1; i<=n; i++)
11265 {
11266 obs=(TObjString*)fDataNames.GetObject(i,1);
11267 var=(TObjString*)fDataNames.GetObject(i,2);
11268 u=(TObjString*)fDataNames.GetObject(i,3);
11269 f=(TObjString*)fDataNames.GetObject(i,4);
11270 cout << " obsname=" << obs->GetString() << " varname=" << var->GetString() << " units=" << u->GetString() << " func=" << f->GetString() << endl;
11271 }
11272 cout << endl;
11273}
11274
11275void NcAstrolab::SetBurstParameter(TString name,Double_t value)
11276{
11417
11418 if (!fBurstParameters)
11419 {
11421 fBurstParameters->SetNameTitle("BurstParameters","Parameter settings for transient burst investigations");
11422 }
11423
11424 if (name!="*")
11425 {
11426 fBurstParameters->AddNamedSlot(name);
11427 if (name=="ESigmax" || name=="Emax") value+=1e-10; // To include the max. energy boundary in the histogram
11428 fBurstParameters->SetSignal(value,name);
11429 }
11430 else
11431 {
11432 Double_t pi=acos(-1.);
11433 name="Nmaxsrc";
11434 fBurstParameters->AddNamedSlot(name);
11435 fBurstParameters->SetSignal(-1,name);
11436 name="Nmaxevt";
11437 fBurstParameters->AddNamedSlot(name);
11438 fBurstParameters->SetSignal(-1,name);
11439 name="RAmin";
11440 fBurstParameters->AddNamedSlot(name);
11441 fBurstParameters->SetSignal(0,name);
11442 name="RAmax";
11443 fBurstParameters->AddNamedSlot(name);
11444 fBurstParameters->SetSignal(360,name);
11445 name="Declmin";
11446 fBurstParameters->AddNamedSlot(name);
11447 fBurstParameters->SetSignal(-90,name);
11448 name="Declmax";
11449 fBurstParameters->AddNamedSlot(name);
11450 fBurstParameters->SetSignal(90,name);
11451 name="T90min";
11452 fBurstParameters->AddNamedSlot(name);
11453 fBurstParameters->SetSignal(1e-5,name);
11454 name="T90max";
11455 fBurstParameters->AddNamedSlot(name);
11456 fBurstParameters->SetSignal(1e5,name);
11457 name="Zmin";
11458 fBurstParameters->AddNamedSlot(name);
11459 fBurstParameters->SetSignal(-1e-6,name);
11460 name="Zmax";
11461 fBurstParameters->AddNamedSlot(name);
11462 fBurstParameters->SetSignal(20,name);
11463 name="Sigmamin";
11464 fBurstParameters->AddNamedSlot(name);
11465 fBurstParameters->SetSignal(0,name);
11466 name="Sigmamax";
11467 fBurstParameters->AddNamedSlot(name);
11468 fBurstParameters->SetSignal(2,name);
11469 name="Grbnu";
11470 fBurstParameters->AddNamedSlot(name);
11471 fBurstParameters->SetSignal(0,name);
11472 name="Dweight";
11473 fBurstParameters->AddNamedSlot(name);
11474 fBurstParameters->SetSignal(1,name);
11475 name="DweightSum"; // Reset the sum of the individual distance weights
11476 fBurstParameters->AddNamedSlot(name);
11477 fBurstParameters->SetSignal(0,name);
11478 name="Avgrbz";
11479 fBurstParameters->AddNamedSlot(name);
11480 fBurstParameters->SetSignal(-1,name);
11481 name="Avgrbt90";
11482 fBurstParameters->AddNamedSlot(name);
11483 fBurstParameters->SetSignal(-1,name);
11484 name="Inburst";
11485 fBurstParameters->AddNamedSlot(name);
11486 fBurstParameters->SetSignal(0,name);
11487 name="Dtnu";
11488 fBurstParameters->AddNamedSlot(name);
11489 fBurstParameters->SetSignal(0,name);
11490 name="Dtnus";
11491 fBurstParameters->AddNamedSlot(name);
11492 fBurstParameters->SetSignal(-0.5,name);
11493 name="ESigmin";
11494 fBurstParameters->AddNamedSlot(name);
11495 fBurstParameters->SetSignal(1e3,name);
11496 name="ESigmax";
11497 fBurstParameters->AddNamedSlot(name);
11498 fBurstParameters->SetSignal(1e10,name);
11499 name="Ezcor";
11500 fBurstParameters->AddNamedSlot(name);
11501 fBurstParameters->SetSignal(1,name);
11502 name="Emin";
11503 fBurstParameters->AddNamedSlot(name);
11504 fBurstParameters->SetSignal(200,name);
11505 name="Emax";
11506 fBurstParameters->AddNamedSlot(name);
11507 fBurstParameters->SetSignal(1e7,name);
11508 name="Alphasig";
11509 fBurstParameters->AddNamedSlot(name);
11510 fBurstParameters->SetSignal(2,name);
11511 name="Alphabkg";
11512 fBurstParameters->AddNamedSlot(name);
11513 fBurstParameters->SetSignal(3.5,name);
11514 name="Kinangle";
11515 fBurstParameters->AddNamedSlot(name);
11516 fBurstParameters->SetSignal(3,name);
11517 name="Angresmin";
11518 fBurstParameters->AddNamedSlot(name);
11519 fBurstParameters->SetSignal(0,name);
11520 name="Angresmax";
11521 fBurstParameters->AddNamedSlot(name);
11522 fBurstParameters->SetSignal(2,name);
11523 name="Angresfix";
11524 fBurstParameters->AddNamedSlot(name);
11525 fBurstParameters->SetSignal(1,name);
11526 name="Recoangle";
11527 fBurstParameters->AddNamedSlot(name);
11528 fBurstParameters->SetSignal(3,name);
11529 name="Sumsigmas";
11530 fBurstParameters->AddNamedSlot(name);
11531 fBurstParameters->SetSignal(2,name);
11532 name="Timres";
11533 fBurstParameters->AddNamedSlot(name);
11534 fBurstParameters->SetSignal(1e-5,name);
11535 name="Sensarea";
11536 fBurstParameters->AddNamedSlot(name);
11537 fBurstParameters->SetSignal(1e6,name);
11538 name="Bkgrate";
11539 fBurstParameters->AddNamedSlot(name);
11540 fBurstParameters->SetSignal(-0.003/(2.*pi),name);
11541 name="Nbkg";
11542 fBurstParameters->AddNamedSlot(name);
11543 fBurstParameters->SetSignal(1,name);
11544 name="Tunits";
11545 fBurstParameters->AddNamedSlot(name);
11546 fBurstParameters->SetSignal(2,name);
11547 name="Tmin";
11548 fBurstParameters->AddNamedSlot(name);
11549 fBurstParameters->SetSignal(-3600,name);
11550 name="Tmax";
11551 fBurstParameters->AddNamedSlot(name);
11552 fBurstParameters->SetSignal(3600,name);
11553 name="Dawin";
11554 fBurstParameters->AddNamedSlot(name);
11555 fBurstParameters->SetSignal(5,name);
11556 name="Datype";
11557 fBurstParameters->AddNamedSlot(name);
11558 fBurstParameters->SetSignal(0,name);
11559 name="Tbint90";
11560 fBurstParameters->AddNamedSlot(name);
11561 fBurstParameters->SetSignal(1,name);
11562 name="Tbin";
11563 fBurstParameters->AddNamedSlot(name);
11564 fBurstParameters->SetSignal(1,name);
11565 name="VarTbin";
11566 fBurstParameters->AddNamedSlot(name);
11567 fBurstParameters->SetSignal(10,name);
11568 name="Abin";
11569 fBurstParameters->AddNamedSlot(name);
11570 fBurstParameters->SetSignal(1,name);
11571 name="BBtime";
11572 fBurstParameters->AddNamedSlot(name);
11573 fBurstParameters->SetSignal(1,name);
11574 name="BBangle";
11575 fBurstParameters->AddNamedSlot(name);
11576 fBurstParameters->SetSignal(1,name);
11577 name="BBfpr";
11578 fBurstParameters->AddNamedSlot(name);
11579 fBurstParameters->SetSignal(-0.05,name);
11580
11581 // Remove all histograms related to burst investigations
11582 fBurstHistos.Clear();
11583 fBurstHistos.SetOwner();
11584 }
11585
11587 // Store some derived parameters //
11589
11590 // The correction factor to get from Tunits to seconds
11591 Int_t fTunits=TMath::Nint(fBurstParameters->GetSignal("Tunits"));
11592 Double_t Tfact=1;
11593 if (fTunits==0) Tfact=86400;
11594 if (fTunits==1) Tfact=3600;
11595 if (fTunits==3) Tfact=1e-9;
11596 if (fTunits==4) Tfact=1e-12;
11597 name="Tfact";
11598 fBurstParameters->AddNamedSlot(name);
11599 fBurstParameters->SetSignal(Tfact,name);
11600
11601 // Combined burst position and event reconstruction angular uncertainty interval (sigma in degrees)
11602 Int_t fSumsigmas=TMath::Nint(fBurstParameters->GetSignal("Sumsigmas"));
11603 Int_t fRecoangle=TMath::Nint(fBurstParameters->GetSignal("Recoangle"));
11604 Float_t fSigmamin=fabs(fBurstParameters->GetSignal("Sigmamin"));
11605 Float_t fAngresmin=fBurstParameters->GetSignal("Angresmin");
11606 Float_t fAngresfix=fBurstParameters->GetSignal("Angresfix");
11607 if (!fRecoangle) fAngresmin=fAngresfix;
11608 Float_t Minsigmatot=-1;
11609 if (fSumsigmas==-1) Minsigmatot=fAngresmin;
11610 if (fSumsigmas==0) Minsigmatot=fSigmamin;
11611 if (fSumsigmas==1) Minsigmatot=fSigmamin+fAngresmin;
11612 if (fSumsigmas==2) Minsigmatot= sqrt(fSigmamin*fSigmamin+fAngresmin*fAngresmin);
11613 name="Minsigmatot";
11614 fBurstParameters->AddNamedSlot(name);
11615 fBurstParameters->SetSignal(Minsigmatot,name);
11616 Float_t fSigmamax=fBurstParameters->GetSignal("Sigmamax");
11617 Float_t fAngresmax=fBurstParameters->GetSignal("Angresmax");
11618 if (!fRecoangle) fAngresmax=fAngresfix;
11619 Float_t Maxsigmatot=-1;
11620 if (fSumsigmas==-1) Maxsigmatot=fAngresmax;
11621 if (fSumsigmas==0) Maxsigmatot=fSigmamax;
11622 if (fSumsigmas==1) Maxsigmatot=fSigmamax+fAngresmax;
11623 if (fSumsigmas==2) Maxsigmatot= sqrt(fSigmamax*fSigmamax+fAngresmax*fAngresmax);
11624 name="Maxsigmatot";
11625 fBurstParameters->AddNamedSlot(name);
11626 fBurstParameters->SetSignal(Maxsigmatot,name);
11627
11628 // The total search time window in units of "Tunits"
11629 Float_t fTmin=fBurstParameters->GetSignal("Tmin");
11630 Float_t fTmax=fBurstParameters->GetSignal("Tmax");
11631 Float_t Dtwin=fTmax-fTmin;
11632 name="Dtwin";
11633 fBurstParameters->AddNamedSlot(name);
11634 fBurstParameters->SetSignal(Dtwin,name);
11635
11636 Float_t fTbin=fBurstParameters->GetSignal("Tbin");
11637 if (!fTbin) // Center the time window around the burst trigger for variable time bins
11638 {
11639 fTmin=-Dtwin/2.;
11640 fTmax=Dtwin/2.;
11641 name="Tmin";
11642 fBurstParameters->AddNamedSlot(name);
11643 fBurstParameters->SetSignal(fTmin,name);
11644 name="Tmax";
11645 fBurstParameters->AddNamedSlot(name);
11646 fBurstParameters->SetSignal(fTmax,name);
11647 }
11648
11649 // The solid angle corresponding to the selected declination band
11650 Float_t fRAmin=fBurstParameters->GetSignal("RAmin");
11651 Float_t fRAmax=fBurstParameters->GetSignal("RAmax");
11652 Float_t fDeclmin=fBurstParameters->GetSignal("Declmin");
11653 Float_t fDeclmax=fBurstParameters->GetSignal("Declmax");
11654 Float_t phimin=fRAmin;
11655 Float_t phimax=fRAmax;
11656 Float_t thmin=90.-fDeclmax;
11657 Float_t thmax=90.-fDeclmin;
11658 Float_t OmegaDecl=GetSolidAngle(thmin,thmax,"deg",phimin,phimax,"deg");
11659 name="OmegaDecl";
11660 fBurstParameters->AddNamedSlot(name);
11661 fBurstParameters->SetSignal(OmegaDecl,name);
11662
11663 // Background event rate from the selected declination band
11664 Float_t fBkgrate=fBurstParameters->GetSignal("Bkgrate");
11665 Float_t RbkgDecl=fBkgrate;
11666 if (fBkgrate<0)
11667 {
11668 RbkgDecl=fabs(fBkgrate)*OmegaDecl;
11669 }
11670 name="RbkgDecl";
11671 fBurstParameters->AddNamedSlot(name);
11672 fBurstParameters->SetSignal(RbkgDecl,name);
11673
11674 // Mean number of background events per hour from the selected declination band
11675 Float_t NbkgHour=RbkgDecl*3600.;
11676 name="NbkgHour";
11677 fBurstParameters->AddNamedSlot(name);
11678 fBurstParameters->SetSignal(NbkgHour,name);
11679
11680 // Mean number of background events in the search time window from the selected declination band
11681 Float_t fDtwin=fBurstParameters->GetSignal("Dtwin");
11682 Float_t NbkgWin=RbkgDecl*fDtwin*Tfact;
11683 name="NbkgWin";
11684 fBurstParameters->AddNamedSlot(name);
11685 fBurstParameters->SetSignal(NbkgWin,name);
11686}
11687
11688Double_t NcAstrolab::GetBurstParameter(TString name)
11689{
11699
11700 Double_t value=fBurstParameters->GetSignal(name);
11701 return value;
11702}
11703
11705{
11715
11716 return fBurstParameters;
11717}
11718
11720{
11730
11731 // User provided settings
11732 Int_t fNmaxsrc=TMath::Nint(fBurstParameters->GetSignal("Nmaxsrc"));
11733 Int_t fNmaxevt=TMath::Nint(fBurstParameters->GetSignal("Nmaxevt"));
11734 Float_t fRAmin=fBurstParameters->GetSignal("RAmin");
11735 Float_t fRAmax=fBurstParameters->GetSignal("RAmax");
11736 Float_t fDeclmin=fBurstParameters->GetSignal("Declmin");
11737 Float_t fDeclmax=fBurstParameters->GetSignal("Declmax");
11738 Float_t fT90min=fBurstParameters->GetSignal("T90min");
11739 Float_t fT90max=fBurstParameters->GetSignal("T90max");
11740 Float_t fZmin=fBurstParameters->GetSignal("Zmin");
11741 Float_t fZmax=fBurstParameters->GetSignal("Zmax");
11742 Float_t fSigmamin=fBurstParameters->GetSignal("Sigmamin");
11743 Float_t fSigmamax=fBurstParameters->GetSignal("Sigmamax");
11744 Float_t fGrbnu=fBurstParameters->GetSignal("Grbnu");
11745 Int_t fDweight=TMath::Nint(fBurstParameters->GetSignal("Dweight"));
11746 Float_t fAvgrbz=fBurstParameters->GetSignal("Avgrbz");
11747 Float_t fAvgrbt90=fBurstParameters->GetSignal("Avgrbt90");
11748 Float_t fAvgrbsigma=fBurstParameters->GetSignal("Avgrbsigma");
11749 Int_t fInburst=TMath::Nint(fBurstParameters->GetSignal("Inburst"));
11750 Float_t fDtnu=fBurstParameters->GetSignal("Dtnu");
11751 Float_t fDtnus=fBurstParameters->GetSignal("Dtnus");
11752 Float_t fESigmin=fBurstParameters->GetSignal("ESigmin");
11753 Float_t fESigmax=fBurstParameters->GetSignal("ESigmax");
11754 Int_t fEzcor=TMath::Nint(fBurstParameters->GetSignal("Ezcor"));
11755 Float_t fEmin=fBurstParameters->GetSignal("Emin");
11756 Float_t fEmax=fBurstParameters->GetSignal("Emax");
11757 Int_t fKinangle=TMath::Nint(fBurstParameters->GetSignal("Kinangle"));
11758 Float_t fAngresmin=fBurstParameters->GetSignal("Angresmin");
11759 Float_t fAngresmax=fBurstParameters->GetSignal("Angresmax");
11760 Float_t fAngresfix=fBurstParameters->GetSignal("Angresfix");
11761 Int_t fRecoangle=TMath::Nint(fBurstParameters->GetSignal("Recoangle"));
11762 Int_t fSumsigmas=TMath::Nint(fBurstParameters->GetSignal("Sumsigmas"));
11763 Float_t fTimres=fBurstParameters->GetSignal("Timres");
11764 Float_t fSensarea=fBurstParameters->GetSignal("Sensarea");
11765 Float_t fBkgrate=fBurstParameters->GetSignal("Bkgrate");
11766 Int_t fNbkg=TMath::Nint(fBurstParameters->GetSignal("Nbkg"));
11767 Float_t fTmin=fBurstParameters->GetSignal("Tmin");
11768 Float_t fTmax=fBurstParameters->GetSignal("Tmax");
11769 Int_t fTunits=TMath::Nint(fBurstParameters->GetSignal("Tunits"));
11770 Float_t fDawin=fBurstParameters->GetSignal("Dawin");
11771 Int_t fDatype=TMath::Nint(fBurstParameters->GetSignal("Datype"));
11772 Int_t fTbint90=TMath::Nint(fBurstParameters->GetSignal("Tbint90"));
11773 Float_t fTbin=fBurstParameters->GetSignal("Tbin");
11774 Float_t fVarTbin=fBurstParameters->GetSignal("VarTbin");
11775 Float_t fAbin=fBurstParameters->GetSignal("Abin");
11776 Int_t fBBtime=TMath::Nint(fBurstParameters->GetSignal("BBtime"));
11777 Int_t fBBangle=TMath::Nint(fBurstParameters->GetSignal("BBangle"));
11778 Float_t fBBfpr=fBurstParameters->GetSignal("BBfpr");
11779
11780 // Derived parameters
11781 Float_t fMaxsigmatot=fBurstParameters->GetSignal("Maxsigmatot");
11782 Float_t fMinsigmatot=fBurstParameters->GetSignal("Minsigmatot");
11783 Float_t fOmegaDecl=fBurstParameters->GetSignal("OmegaDecl");
11784 Float_t fRbkgDecl=fBurstParameters->GetSignal("RbkgDecl");
11785 Float_t fNbkgHour=fBurstParameters->GetSignal("NbkgHour");
11786 Float_t fNbkgWin=fBurstParameters->GetSignal("NbkgWin");
11787
11788 // Internal statistics
11789 Int_t fNgrbs=TMath::Nint(fBurstParameters->GetSignal("Ngrbs"));
11790 Int_t fNevts=TMath::Nint(fBurstParameters->GetSignal("Nevts"));
11791
11792 TString tu="days";
11793 if (fTunits==1) tu="hours";
11794 if (fTunits==2) tu="sec";
11795 if (fTunits==3) tu="ns";
11796 if (fTunits==4) tu="ps";
11797
11798 cout << " ========================= User provided source c.q. burst settings ===============================" << endl;
11799 if (fNmaxsrc<0)
11800 {
11801 printf(" No limitation has been put on the number of sources to be accepted for analysis. \n");
11802 }
11803 else
11804 {
11805 printf(" Maximal number of sources to be accepted for analysis : %-i \n",fNmaxsrc);
11806 }
11807 if (fNmaxevt<0)
11808 {
11809 printf(" No limitation has been put on the number of observed events to be accepted for analysis. \n");
11810 }
11811 else
11812 {
11813 printf(" Maximal number of observed events to be accepted for analysis : %-i \n",fNmaxevt);
11814 }
11815 printf(" Right ascension interval (J2000 in degrees) for source c.q. event position acceptance : [%-g,%-g] \n",fRAmin,fRAmax);
11816 printf(" Declination interval (J2000 in degrees) for source c.q. event position acceptance : [%-g,%-g] \n",fDeclmin,fDeclmax);
11817 printf(" Redshift interval for source acceptance : [%-g,%-g] \n",fabs(fZmin),fZmax);
11818 if (fZmin<0) printf(" Random redshift values taken from z-distribution in case of unknown redshift \n");
11819 if (fAvgrbz>=0) printf(" User defined average source redshift : %-g \n",fAvgrbz);
11820 printf(" Event energy interval (in GeV) for event acceptance : [%-g,%-g] \n",fEmin,fEmax);
11821 printf(" Position uncertainty interval (sigma in degrees) for source acceptance : [%-g,%-g] \n",fabs(fSigmamin),fSigmamax);
11822 if (fSigmamin<0) printf(" Random sigma values taken from sigma-distribution when missing in loaded data \n");
11823 printf(" Event angular resolution interval (sigma in degrees) for event acceptance : [%-g,%-g] \n",fAngresmin,fAngresmax);
11824 if (fDatype>0) printf(" Sigma (combination) selection (-1=event sigma only 0=source sigma only 1=linear summation 2=quadratic summation) : %-i \n",fSumsigmas);
11825 if (fDawin>=0)
11826 {
11827 if (fDatype<0) printf(" Unrestricted angular search area. \n");
11828 if (!fDatype) printf(" Fixed angular search circle around the source position : %-g degrees \n",fDawin);
11829 if (fDatype==1) printf(" Fixed angular search circle (in combined max. source/event sigma) around the source position : %-g \n",fDawin);
11830 if (fDatype==2) printf(" Variable angular search circle (in combined actual source/event sigma) around the source position : %-g \n",fDawin);
11831 }
11832 else
11833 {
11834 if (fDatype<0) printf(" Unrestricted angular search area. \n");
11835 if (!fDatype) printf(" Fixed angular local zenith band above/below the source position : %-g degrees \n",fabs(fDawin));
11836 if (fDatype==1) printf(" Fixed angular local zenith band (in combined max. source/event sigma) above/below the source position : %-g \n",fabs(fDawin));
11837 if (fDatype==2) printf(" Variable angular local zenith band (in combined actual source/event sigma) above/below the source position : %-g \n",fabs(fDawin));
11838 }
11839 printf(" Number of requested background patches per source : %-i \n",fNbkg);
11840 if (fT90max>0)
11841 {
11842 printf(" Duration interval (t90 in sec) for burst acceptance : [%-g,%-g] \n",fabs(fT90min),fT90max);
11843 if (fT90min<0) printf(" Random values taken from T90-distribution in case T90 and T100 were missing \n");
11844 if (fAvgrbt90>0) printf(" User defined average burst T90 duration : %-g sec. \n",fAvgrbt90);
11845 if (fTmax>fTmin) printf(" Total search time window (in %-s) with the burst trigger at t=0 : [%-g,%-g] \n",tu.Data(),fTmin,fTmax);
11846 }
11847 if (fTmax<=fTmin) printf(" Search will be performed with no restrictions on the time window \n");
11848 if (fTbin<0) printf(" Automatic time histogram binning with as mean number of bkg counts/bin : %-g \n",fabs(fTbin));
11849 if (!fTbin) printf(" Variable time histogram binning with as size (in %-s) for the first time : %-g \n",tu.Data(),fVarTbin);
11850 if (fTbin>0)
11851 {
11852 if (fTbint90)
11853 {
11854 printf(" Time histogram bin size in average T90 units : %-g",fTbin);
11855 if (fAvgrbt90>0 || fNgrbs>0) printf(" (=%-g sec)",fTbin*fabs(fAvgrbt90));
11856 printf("\n");
11857 }
11858 else
11859 {
11860 printf( " Time histogram bin size : %-g %-s \n",fTbin,tu.Data());
11861 }
11862 }
11863 if (fAbin<0)
11864 {
11865 printf(" Automatic angular histogram binning with as mean number of bkg counts per bin : %-g \n",fabs(fAbin));
11866 }
11867 else
11868 {
11869 printf(" Angular histogram bin size : %-g degrees \n",fAbin);
11870 }
11871
11872 if (fBBtime)
11873 {
11874 printf(" Bayesian Block data will be created for the arrival times. \n");
11875 }
11876 else
11877 {
11878 printf(" No Bayesian Block data will be created for the arrival times. \n");
11879 }
11880 if (fBBangle)
11881 {
11882 printf(" Bayesian Block data will be created for the cosine of the opening angles. \n");
11883 }
11884 else
11885 {
11886 printf(" No Bayesian Block data will be created for the cosine of the opening angles. \n");
11887 }
11888 if (fBBtime || fBBangle) printf(" False positive rate parameter for Bayesian Block processing : %-g \n",fBBfpr);
11889
11890 // Parameters for burst signal and background generation
11891 if (fGrbnu)
11892 {
11893 if (!fInburst)
11894 {
11895 printf(" Neutrino production is assumed to be NOT coupled to the observed burst duration \n");
11896 printf(" Mean decoupled time difference between burst gammas/GW and neutrinos : %-g sec. \n",fDtnu);
11897 }
11898 else
11899 {
11900 printf(" Neutrino production is assumed to be coupled to the observed burst duration \n");
11901 printf(" Mean coupled time difference (in units of T90 w.r.t. trigger) between burst gammas/GW and neutrinos : %-g",fDtnu);
11902 }
11903
11904 if (fDtnus>=0)
11905 {
11906 printf(" Sigma of mean time difference between burst gammas/GW flash and neutrinos : %-g sec. \n",fDtnus);
11907 }
11908 else
11909 {
11910 printf(" Sigma of mean time difference (in units of T90) between burst gammas/GW flash and neutrinos : %-g \n",fabs(fDtnus));
11911 }
11912
11913 TString str;
11914 if (fSigEmode=="SigE")
11915 {
11916 str="Signal energy PDF at the source : dN/dE=";
11917 }
11918 else
11919 {
11920 str="Per source signal energy profile at Earth : dN/dE=";
11921 }
11922 str+=fSigEprofile.GetExpFormula("p");
11923 str.ReplaceAll("x","E");
11924 if (fSigEmode=="SigS")
11925 {
11926 str.ReplaceAll("dE","(dEdA)");
11927 str+=" cm^-2";
11928 }
11929 if (fSigEmode=="SigF")
11930 {
11931 str.ReplaceAll("dE","(dEdAdt)");
11932 str+=" cm^-2 s^-1";
11933 }
11934 if (fSigEmode=="SigI")
11935 {
11936 str.ReplaceAll("dE","(dEdAdtdOmega)");
11937 str+=" cm^-2 s^-1 sr^-1";
11938 }
11939 printf(" %-s within [%-g,%-g] GeV \n",str.Data(),fESigmin,fESigmax);
11940
11941 if (fSigEmode=="SigE")
11942 {
11943 if (fEzcor)
11944 {
11945 printf(" The signal neutrino energy at Earth will be corrected for redshift \n");
11946 }
11947 else
11948 {
11949 printf(" No redshift correction will be applied on the generated signal neutrino energy \n");
11950 }
11951 }
11952 else if (fSigEmode=="SigS" || fSigEmode=="SigF" || fSigEmode=="SigI")
11953 {
11954 if (fDweight)
11955 {
11956 printf(" The signal contribution of each individual source will be determined based on a distance weight \n");
11957 }
11958 else
11959 {
11960 printf(" No distance weight will be applied for the signal contribution of individual sources \n");
11961 }
11962 }
11963
11964 if (fGrbnu<0)
11965 {
11966 if (fSigEmode=="SigE")
11967 {
11968 printf(" Number of generated neutrinos per burst : %-g without statistical fluctuations \n",fabs(fGrbnu));
11969 }
11970 else
11971 {
11972 printf(" Signal neutrinos are generated without Poisson fluctuation of the expected average counts \n");
11973 }
11974 }
11975 else
11976 {
11977 if (fSigEmode=="SigE")
11978 {
11979 printf(" Average number of generated neutrinos per burst : %-g \n",fGrbnu);
11980 printf(" The actual number of neutrinos may vary due to statistical (Poisson) fluctuations \n");
11981 }
11982 else
11983 {
11984 printf(" Signal neutrinos are generated with Poisson fluctuation of the expected average counts \n");
11985 }
11986 }
11987
11988 if (fBkgEmode=="BkgE")
11989 {
11990 str="Background energy PDF at Earth : dN/dE=";
11991 }
11992 else
11993 {
11994 str="Background energy profile at Earth : dN/dE=";
11995 }
11996 str+=fBkgEprofile.GetExpFormula("p");
11997 str.ReplaceAll("x","E");
11998 if (fBkgEmode=="BkgS")
11999 {
12000 str.ReplaceAll("dE","(dEdA)");
12001 str+=" cm^-2";
12002 }
12003 if (fBkgEmode=="BkgF")
12004 {
12005 str.ReplaceAll("dE","(dEdAdt)");
12006 str+=" cm^-2 s^-1";
12007 }
12008 if (fBkgEmode=="BkgI")
12009 {
12010 str.ReplaceAll("dE","(dEdAdtdOmega)");
12011 str+=" cm^-2 s^-1 sr^-1";
12012 }
12013 printf(" %-s within [%-g,%-g] GeV \n",str.Data(),fEmin,fEmax);
12014
12015 printf(" Fixed event reco angular resolution (sigma in degrees), also used when no distribution (value) is available : %-g \n",fAngresfix);
12016 printf(" Event reconstruction angular uncertainty selection (0=use fixed value 1=mean 2=median 3=draw from distribution) : %-i \n",fRecoangle);
12017 printf(" Neutrino-lepton kinematic opening angle selection for CC interactions (0=none 1=mean 2=median 3=draw from pdf) : %-i \n",fKinangle);
12018 }
12019
12020 printf("\n");
12021 printf(" Time resolution of the neutrino detector : %-g sec. \n",fTimres);
12022 printf(" Area covered c.q. overlooked by the neutrino detector : %-g m^2 \n",fSensarea);
12023 if (fBkgEmode=="BkgE" && fBkgrate)
12024 {
12025 printf(" User defined mean rate of background events for the specified declination interval (<0 : rate per steradian) : %-g Hz \n",fBkgrate);
12026 }
12027
12028 printf("\n");
12029 printf(" ============================== Derived parameters ==================================== \n");
12030 printf(" Combined source position and event reco angular uncertainty interval (sigma in degrees) : [%-g,%-g] \n",fMinsigmatot,fMaxsigmatot);
12031 printf(" Solid angle coverage corresponding to the selected RA and DEC range : %-g steradian \n",fOmegaDecl);
12032 if (fBkgEmode=="BkgE" && fBkgrate)
12033 {
12034 printf(" Background event rate (from user setting) for the selected RA and DEC range : %-g Hz \n",fRbkgDecl);
12035 printf(" Mean number of background events (from user setting) per hour from the selected RA and DEC range : %-g \n",fNbkgHour);
12036 printf(" Mean number of background events (from user setting) in the time window from the selected RA and DEC range : %-g \n",fNbkgWin);
12037 }
12038 if (fNgrbs>0)
12039 {
12040 printf(" Number of bursts accepted for analysis : %-i \n",fNgrbs);
12041 printf(" Median source redshift from the data sample : %-g \n",fabs(fAvgrbz));
12042 if (fAvgrbt90) printf(" Median burst T90 duration from the data sample : %-g sec. \n",fabs(fAvgrbt90));
12043 printf(" Median souce position uncertainty (sigma in degrees) from the data sample : %-g \n",fAvgrbsigma);
12044 }
12045 if (fNevts>0) printf(" Number of observed events accepted for analysis : %-i \n",fNevts);
12046 printf(" ====================================================================================== \n");
12047 printf("\n");
12048}
12049
12050void NcAstrolab::LoadInputData(Bool_t src,TString file,TString tree,Int_t date1,Int_t date2,Int_t nmax,TString type)
12051{
12108
12109 // Set the default type identifier
12110 if (type=="-" && src) type="GRB";
12111 if (type=="-" && !src) type="EVT";
12112
12113 Int_t nvars=fDataNames.GetMaxRow();
12114
12115 if (nvars<1)
12116 {
12117 cout << " *" << ClassName() << "::LoadInputData* No variables were specified for " << type << " data."<< endl;
12118 return;
12119 }
12120
12121 // Set the data mode : observed events or source data
12122 Int_t iobs=1;
12123 if (src) iobs=0;
12124
12125 // Retreive the needed parameters
12126 Int_t fNmaxsrc=TMath::Nint(fBurstParameters->GetSignal("Nmaxsrc"));
12127 Int_t fNmaxevt=TMath::Nint(fBurstParameters->GetSignal("Nmaxevt"));
12128 Float_t fRAmin=fBurstParameters->GetSignal("RAmin");
12129 Float_t fRAmax=fBurstParameters->GetSignal("RAmax");
12130 Float_t fDeclmin=fBurstParameters->GetSignal("Declmin");
12131 Float_t fDeclmax=fBurstParameters->GetSignal("Declmax");
12132 Float_t fT90min=fBurstParameters->GetSignal("T90min");
12133 Float_t fT90max=fBurstParameters->GetSignal("T90max");
12134 Float_t fZmin=fBurstParameters->GetSignal("Zmin");
12135 Float_t fZmax=fBurstParameters->GetSignal("Zmax");
12136 Float_t fSigmamin=fBurstParameters->GetSignal("Sigmamin");
12137 Float_t fSigmamax=fBurstParameters->GetSignal("Sigmamax");
12138 Float_t fEmin=fBurstParameters->GetSignal("Emin");
12139 Float_t fEmax=fBurstParameters->GetSignal("Emax");
12140 Float_t fAngresmin=fBurstParameters->GetSignal("Angresmin");
12141 Float_t fAngresmax=fBurstParameters->GetSignal("Angresmax");
12142 Int_t fDweight=TMath::Nint(fBurstParameters->GetSignal("Dweight"));
12143
12144 // Internal statistics
12145 Int_t fNgrbs=GetNsignals(0);
12146 Int_t fNevts=GetNsignals(1);
12147
12148 // Get access to a redshift distribution to draw randomly source redshifts if needed
12149 TH1* zdist=0;
12150 if (src && fZmin<0) zdist=GetBurstZdist("LoadInputData()",type);
12151
12152 // Get access to a T90 distribution to draw randomly source c.q. burst T90 values if needed
12153 TH1* t90dist=0;
12154 if (src && fT90min<0) t90dist=GetBurstT90dist("LoadInputData()",type);
12155
12156 // Get access to a 1-sigma position uncertainty distribution to draw randomly source position uncertaintes
12157 TH1* sigmaposdist=0;
12158 if (src && fSigmamin<0) sigmaposdist=GetBurstSigmaPosdist("LoadInputData()",type);
12159
12160 // The TTree containing the source (c.q. burst) or observed event data
12161 TChain data(tree.Data());
12162 data.Add(file.Data());
12163
12164 // The pre-defined (physical) observables
12165 TString obsname;
12166 TString varname;
12167 TString units;
12168 TString func;
12169
12170 // The (physical) observable value in string format
12171 TObjString* pval=0;
12172 TString val;
12173
12174 // The retrieved numerical (physical) observable value from the ROOT Tree
12175 Double_t value=0;
12176
12177 // The conversion factor depending on the units specification
12178 Double_t fact=0;
12179
12180 // Some of the pre-defined observable values that are used for selections
12181 // or that need special treatment
12182 TString Name,Date,Tobs,Tstart,Tend;
12183 Double_t d,a,b;
12184 Float_t z,csigma,T90,T100,E;
12185
12186 UInt_t yyyy,mm,dd; // The date format
12187 Int_t h,m; // The integer hour and minute time format
12188 Double_t s; // The (fractional) seconds time format
12189 Int_t dmode=0;
12190 Int_t idate=0;
12191 Int_t jdate=0;
12192 TString grbname;
12193 NcTimestamp tobs;
12194 NcTimestamp tstart;
12195 NcTimestamp tend;
12196 NcSignal* sx=0;
12197 Int_t nnew=0;
12198 TLeaf* lx=0;
12199 TLeafC* lxc=0;
12200 Int_t jlast=0;
12201
12202 // Create or increase the corresponding storage array to hold the new data
12203 Int_t nent=data.GetEntries();
12204 Int_t size=0;
12205 if (src) // Input represents reference objects
12206 {
12207 if (!fRefs)
12208 {
12209 fRefs=new TObjArray(nent);
12210 fRefs->SetOwner();
12211 }
12212 else
12213 {
12214 size=fRefs->GetSize();
12215 fRefs->Expand(size+nent);
12216 }
12217 }
12218 else // Input represents measured signals
12219 {
12220 if (!fSigs)
12221 {
12222 fSigs=new TObjArray(nent);
12223 fSigs->SetOwner();
12224 }
12225 else
12226 {
12227 size=fSigs->GetSize();
12228 fSigs->Expand(size+nent);
12229 }
12230 }
12231
12232 // Loop over the data entries in the input Tree
12233 for (Int_t ient=0; ient<nent; ient++)
12234 {
12235 if (nmax>=0 && nnew>=nmax) break;
12236 if (src && fNmaxsrc>=0 && (fNgrbs+nnew)>=fNmaxsrc) break;
12237 if (!src && fNmaxevt>=0 && (fNevts+nnew)>=fNmaxevt) break;
12238
12239 data.GetEntry(ient);
12240
12241 // Initialisation of the values that are used for selections
12242 // or that need special treatment
12243 Name="none";
12244 Date="none";
12245 Tobs="none";
12246 Tstart="none";
12247 Tend="none";
12248 d=-999;
12249 a=-999;
12250 b=-999;
12251 z=-999;
12252 csigma=-999;
12253 T90=-999;
12254 T100=-999;
12255 E=-999;
12256
12257 // Loop over the selected input variables and retrieve the corresponding input value
12258 for (Int_t ivar=1; ivar<=nvars; ivar++)
12259 {
12260 obsname=((TObjString*)fDataNames.GetObject(ivar,1))->GetString();
12261 varname=((TObjString*)fDataNames.GetObject(ivar,2))->GetString();
12262 units=((TObjString*)fDataNames.GetObject(ivar,3))->GetString();
12263 func=((TObjString*)fDataNames.GetObject(ivar,4))->GetString();
12264
12265 pval=(TObjString*)fDataNames.GetObject(ivar,5);
12266
12267 if (!pval) continue;
12268
12269 lx=data.GetLeaf(varname);
12270
12271 // Record -999 for missing data
12272 if (!lx)
12273 {
12274 pval->SetString("-999");
12275 continue;
12276 }
12277
12278 if (obsname=="Name") // Character string data from the input Tree
12279 {
12280 value=0;
12281 lxc=(TLeafC*)lx;
12282 Name=lxc->GetValueString();
12283 }
12284 else // Numerical data from the input Tree
12285 {
12286 value=lx->GetValue();
12287 }
12288
12289 if (func=="Log") value=pow(10,value);
12290 if (func=="Ln") value=exp(value);
12291
12292 // Convert all angular values to degrees
12293 if (obsname=="a" || obsname=="b" || obsname=="csigma") value=ConvertAngle(value,units,"deg");
12294
12295 // Convert numerical values to the standard units
12296 if (units.IsFloat())
12297 {
12298 fact=units.Atof();
12299 value*=fact;
12300 }
12301
12302 // Store the obtained value in string format
12303 val="";
12304 val+=value;
12305 pval->SetString(val);
12306
12307 // Special values needed for later selections
12308 if (obsname=="Date")
12309 {
12310 Date="";
12311 Date+=int(value);
12312 if (units=="ddmmyyyy") dmode=0;
12313 if (units=="yyyymmdd") dmode=1;
12314 if (units=="mmddyyyy") dmode=2;
12315 if (units=="yyyyddmm") dmode=3;
12316 }
12317 if (obsname=="Tobs")
12318 {
12319 Tobs="set"; // Indicate that Tobs is encountered
12320 if (units=="JD") tobs.SetJD(value);
12321 if (units=="MJD") tobs.SetMJD(value);
12322 if (units=="TJD") tobs.SetTJD(value);
12323 if (units=="hms")
12324 {
12325 Tobs="";
12326 Tobs+=value;
12327 }
12328 if (units=="hrs") // Convert "hrs" to "hms" time format
12329 {
12330 Tobs="";
12331 Convert(value,h,m,s);
12332 value=s+double(100*m+10000*h);
12333 Tobs+=value;
12334 }
12335 }
12336 if (obsname=="Tstart")
12337 {
12338 Tstart="set"; // Indicate that Tstart is encountered
12339 if (units=="JD") tstart.SetJD(value);
12340 if (units=="MJD") tstart.SetMJD(value);
12341 if (units=="TJD") tstart.SetTJD(value);
12342 if (units=="hms")
12343 {
12344 Tstart="";
12345 Tstart+=value;
12346 }
12347 if (units=="hrs") // Convert "hrs" to "hms" time format
12348 {
12349 Tstart="";
12350 Convert(value,h,m,s);
12351 value=s+double(100*m+10000*h);
12352 Tstart+=value;
12353 }
12354 }
12355 if (obsname=="Tend")
12356 {
12357 Tend="set"; // Indicate that Tend is encountered
12358 if (units=="JD") tend.SetJD(value);
12359 if (units=="MJD") tend.SetMJD(value);
12360 if (units=="TJD") tend.SetTJD(value);
12361 if (units=="hms")
12362 {
12363 Tend="";
12364 Tend+=value;
12365 }
12366 if (units=="hrs") // Convert "hrs" to "hms" time format
12367 {
12368 Tend="";
12369 Convert(value,h,m,s);
12370 value=s+double(100*m+10000*h);
12371 Tend+=value;
12372 }
12373 }
12374
12375 if (obsname=="d") d=value;
12376 if (obsname=="a") a=value;
12377 if (obsname=="b") b=value;
12378 if (obsname=="z") z=value;
12379 if (obsname=="csigma") csigma=value;
12380 if (obsname=="T90") T90=value;
12381 if (obsname=="T100") T100=value;
12382 if (obsname=="E") E=value;
12383 } // End of the loop over the selected input variables
12384
12385 // For angular coordinates the distance may be irrelevant
12386 if (d<=0) d=1;
12387
12388 // Check for the presence of valid location data
12389 if (a<-900 || b<-900) continue;
12390
12391 // Check on (RA,DEC) acceptance in case of J2000 equatorial coordinates
12392 if (fDataFrame=="equ" && fDataMode=="J" && (a<fRAmin || a>fRAmax || b<fDeclmin || b>fDeclmax)) continue;
12393
12394 // Construct the various timestamps from the (date,time) specification if needed
12395 if (Tobs!="none" && Tobs!="set" && Date!="none") tobs.SetUT(Date,Tobs,dmode);
12396 if (Tstart!="none" && Tstart!="set" && Date!="none") tstart.SetUT(Date,Tstart,dmode);
12397 if (Tend!="none" && Tend!="set" && Date!="none") tend.SetUT(Date,Tend,dmode);
12398
12399 // Check for the presence of a valid observation c.q. trigger timestamp
12400 if (Tobs=="none" || (Tobs!="set" && Date=="none")) continue;
12401
12402 // Obtain the date in yyyymmdd format
12403 tobs.GetDate(kTRUE,0,&yyyy,&mm,&dd);
12404 idate=dd+100*mm+10000*yyyy;
12405
12406 if (Name!="none") // Set the name of the object or observation
12407 {
12408 grbname=Name;
12409 }
12410 else // Compose the name of the source c.q. burst with the common yymmdd suffix
12411 {
12412 jdate=idate%1000000;
12413 grbname=type;
12414 if (jdate<100000) grbname+="0"; // Add leading zero for the year if needed
12415 grbname+=jdate;
12416 }
12417
12418 if (date1 && idate<date1) continue;
12419 if (date2 && idate>date2) continue;
12420
12421 if (src) // Source c.q. burst specific selections
12422 {
12423 if (T90<=0) T90=T100;
12424 if (fT90min<0 && T90<0 && t90dist) T90=t90dist->GetRandom();
12425
12426 if (T90<fabs(fT90min) || T90>fT90max) continue;
12427
12428 if (fZmin<0 && z<0 && zdist) z=zdist->GetRandom();
12429
12430 if (z<fabs(fZmin) || z>fZmax) continue;
12431
12432 if (fSigmamin<0 && csigma<0 && sigmaposdist) csigma=sigmaposdist->GetRandom();
12433
12434 if (csigma<fabs(fSigmamin) || csigma>fSigmamax) continue;
12435 }
12436 else // Observed event specific selections
12437 {
12438 if (E<fEmin || E>fEmax) continue;
12439 if (csigma<fAngresmin || csigma>fAngresmax) continue;
12440 }
12441
12442 // Store the location c.q. arrival direction data
12443 sx=SetSignal(d,a,"deg",b,"deg",fDataFrame,&tobs,-1,fDataMode,grbname,iobs);
12444
12445 // Obtain the RA and DEC coordinates for acceptance selection if input was not in J2000
12446 if (fDataFrame!="equ" || fDataMode!="J")
12447 {
12448 jlast=GetSignalIndex(sx,iobs);
12449 GetSignal(d,a,"deg",b,"deg","equ",&tobs,jlast,"J",iobs);
12450
12451 // Remove the signal again when it falls outside the acceptance
12452 if (a<fRAmin || a>fRAmax || b<fDeclmin || b>fDeclmax)
12453 {
12454 RemoveSignal(jlast,iobs,0);
12455 sx=0;
12456 continue;
12457 }
12458 }
12459
12460 if (!sx) continue;
12461
12462 nnew++;
12463
12464 // Storing the requested data in NcSignal slots
12465 for (Int_t ivar=1; ivar<=nvars; ivar++)
12466 {
12467 obsname=((TObjString*)fDataNames.GetObject(ivar,1))->GetString();
12468 val=((TObjString*)fDataNames.GetObject(ivar,5))->GetString();
12469
12470 // The observable Name is not stored in the NcSignal slots
12471 if (obsname=="Name") continue;
12472
12473 value=val.Atof();
12474
12475 // The values of the observables a and b depend on the reference frame
12476 // They should be retrieved via the GetSignal() facility
12477 if (obsname=="a" || obsname=="b") continue;
12478
12479 // The Date and timestamps in specific format
12480 if (obsname=="Date") value=idate;
12481 if (obsname=="Tobs") value=tobs.GetMJD();
12482 if (obsname=="Tstart") value=tstart.GetMJD();
12483 if (obsname=="TEnd") value=tend.GetMJD();
12484
12485 // Values that may have got random values
12486 if (obsname=="z")
12487 {
12488 value=z;
12489 // Determine the distance weight for this burst and update the distance weight sum
12490 if (fDweight)
12491 {
12492 d=GetPhysicalDistance(z,"Gpc");
12493 if (d>0)
12494 {
12495 sx->AddNamedSlot("Dweight");
12496 sx->SetSignal(1./pow(d,2),"Dweight");
12497 fBurstParameters->AddSignal(1./pow(d,2),"DweightSum");
12498 }
12499 }
12500 }
12501 if (obsname=="csigma") value=csigma;
12502 if (obsname=="T90") value=T90;
12503
12504 sx->AddNamedSlot(obsname);
12505 sx->SetSignal(value,obsname);
12506 }
12507
12508 if (!src) continue;
12509 } // End of loop over the entries of the input Tree
12510
12511 // Compress the storage array size to the number of actually stored elements
12512 RemoveSignal(-1,iobs,1);
12513
12514 Int_t nstored=GetNsignals(iobs);
12515
12516 cout << endl;
12517 if (src)
12518 {
12519 // Update internal statistics
12520 fBurstParameters->AddNamedSlot("Ngrbs");
12521 fBurstParameters->SetSignal(nstored,"Ngrbs");
12522 cout << " *" << ClassName() << "::LoadInputData* " << nnew << " new source(s) of type " << type
12523 << " stored from Tree:" << tree << " of file(s):" << file << endl;
12524 cout << " Total number of stored sources c.q. bursts : " << nstored << endl;
12525 }
12526 else
12527 {
12528 // Update internal statistics
12529 fBurstParameters->AddNamedSlot("Nevts");
12530 fBurstParameters->SetSignal(nstored,"Nevts");
12531 cout << " *" << ClassName() << "::LoadInputData* " << nnew
12532 << " new observed event(s) were stored from Tree:" << tree << " of file(s):" << file << endl;
12533 cout << " Total number of stored events : " << nstored << endl;
12534 }
12535}
12536
12537void NcAstrolab::LoadAeffData(TString file,TString hist)
12538{
12560
12561 // Expand the input file pathname
12562 file=gSystem->ExpandPathName(file.Data());
12563
12564 TFile f(file.Data());
12565 TH2* h=(TH2*)f.Get(hist.Data());
12566
12567 if (!h)
12568 {
12569 printf("*%-s::LoadAeffData* No 2D histogram with Aeff data found with name : %-s \n",ClassName(),hist.Data());
12570 return;
12571 }
12572
12573 TH2* hAeffProfile=(TH2*)h->Clone("hAeffProfile");
12574 hAeffProfile->SetDirectory(0); // Disonnect this histogram from the TFile f
12575
12576 fBurstHistos.Add(hAeffProfile);
12577
12578 printf("\n *%-s::LoadAeffData* 2D histogram hAeffProfile(log(E),cos(theta)) with effective area data stored. \n",ClassName());
12579 printf(" The data were obtained from the file : %-s \n",file.Data());
12580
12581 // Create a signal and/or background NuCount and Zenith profile by using the corresponding energy profile(s), if any.
12583}
12584
12586{
12604
12605 Double_t fESigmin=fBurstParameters->GetSignal("ESigmin");
12606 Double_t fESigmax=fBurstParameters->GetSignal("ESigmax");
12607 Double_t fEmin=fBurstParameters->GetSignal("Emin");
12608 Double_t fEmax=fBurstParameters->GetSignal("Emax");
12609
12610 TH2* hAeffProfile=(TH2*)fBurstHistos.FindObject("hAeffProfile");
12611 TH1* hSigEprofile=(TH1*)fBurstHistos.FindObject("hSigEprofile");
12612 TH1* hBkgEprofile=(TH1*)fBurstHistos.FindObject("hBkgEprofile");
12613
12614 if (!hAeffProfile) return;
12615
12616 TAxis* xaxis=hAeffProfile->GetXaxis();
12617 TAxis* yaxis=hAeffProfile->GetYaxis();
12618
12619 if (!xaxis || !yaxis) return;
12620
12621 Int_t nebins=xaxis->GetNbins();
12622 Double_t emin=xaxis->GetXmin();
12623 Double_t emax=xaxis->GetXmax();
12624
12625 Int_t nabins=yaxis->GetNbins();
12626 Double_t amin=yaxis->GetXmin();
12627 Double_t amax=yaxis->GetXmax();
12628
12629 TH2* hSigNuCountProfile=(TH2*)fBurstHistos.FindObject("hSigNuCountProfile");
12630 TH2* hBkgNuCountProfile=(TH2*)fBurstHistos.FindObject("hBkgNuCountProfile");
12631 TH1* hSigZenithProfile=(TH1F*)fBurstHistos.FindObject("hSigZenithProfile");
12632 TH1* hBkgZenithProfile=(TH1F*)fBurstHistos.FindObject("hBkgZenithProfile");
12633
12634 Double_t aeff=0;
12635 Double_t integral=0;
12636 Double_t count=0;
12637 Double_t xlow=0;
12638 Double_t xup=0;
12639 TString title="";
12640
12641 // Create the distributions for signal data
12642 if (hSigEprofile && (mode=="Aeff" || mode=="SigS" || mode=="SigF" || mode=="SigI"))
12643 {
12644 title="Contraction of hSigEprofile and hAeffProfile;Log(E/1GeV);Cosine of the Zenith angle (#theta);Counts";
12645 if (mode.Contains("F")) title+=" s^{-1}";
12646 if (mode.Contains("I")) title+=" s^{-1} sr^{ -1}";
12647 if (!hSigNuCountProfile)
12648 {
12649 hSigNuCountProfile=(TH2*)hAeffProfile->Clone("hSigNuCountProfile");
12650 hSigNuCountProfile->Reset();
12651 hSigNuCountProfile->SetTitle(title);
12652 fBurstHistos.Add(hSigNuCountProfile);
12653 }
12654 else if (mode.Contains("Sig")) // Only renew in case of a new Signal energy profile
12655 {
12656 hSigNuCountProfile->Reset();
12657 hSigNuCountProfile->SetBins(nebins,emin,emax,nabins,amin,amax);
12658 hSigNuCountProfile->SetTitle(title);
12659 }
12660
12661 for (Int_t abin=1; abin<=nabins; abin++) // Loop over the cos(theta) bins
12662 {
12663 for (Int_t ebin=1; ebin<=nebins; ebin++) // Loop over the energy bins of hAeffProfile for this theta bin
12664 {
12665 xlow=xaxis->GetBinLowEdge(ebin);
12666 xup=xaxis->GetBinUpEdge(ebin);
12667 xlow=pow(10,xlow);
12668 xup=pow(10,xup);
12669 if (xup<fESigmin || xlow>fESigmax) continue;
12670 if (xlow<fESigmin && xup>fESigmin) xlow=fESigmin;
12671 if (xup>fESigmax && xlow<fESigmax) xup=fESigmax;
12672 aeff=hAeffProfile->GetBinContent(ebin,abin);
12673 integral=fSigEprofile.Integral(xlow,xup);
12674 count=aeff*integral;
12675 hSigNuCountProfile->SetBinContent(ebin,abin,count);
12676 }
12677 }
12678
12679 // Create also the Zenith profile
12680 title="Projection of hSigNuCountProfile;Cosine of the Zenith angle (#theta);Counts";
12681 if (mode.Contains("F")) title+=" s^{-1}";
12682 if (mode.Contains("I")) title+=" s^{-1} sr^{ -1}";
12683
12684 if (!hSigZenithProfile)
12685 {
12686 hSigZenithProfile=hSigNuCountProfile->ProjectionY("hSigZenithProfile");
12687 fBurstHistos.Add(hSigZenithProfile);
12688 }
12689 else if (mode.Contains("Sig")) // Only renew in case of a new Signal energy profile
12690 {
12691 delete hSigZenithProfile;
12692 hSigZenithProfile=hSigNuCountProfile->ProjectionY("hSigZenithProfile");
12693 }
12694 hSigZenithProfile->SetTitle(title);
12695 }
12696
12697 // Create the distributions for background data
12698 if (hBkgEprofile && (mode=="Aeff" || mode=="BkgS" || mode=="BkgF" || mode=="BkgI"))
12699 {
12700 title="Contraction of hBkgEprofile and hAeffProfile;Log(E) in GeV;Cosine of the Zenith angle (#theta);Counts";
12701 if (mode.Contains("F")) title+=" s^{-1}";
12702 if (mode.Contains("I")) title+=" s^{-1} sr^{ -1}";
12703
12704 if (!hBkgNuCountProfile)
12705 {
12706 hBkgNuCountProfile=(TH2*)hAeffProfile->Clone("hBkgNuCountProfile");
12707 hBkgNuCountProfile->Reset();
12708 hBkgNuCountProfile->SetTitle(title);
12709 fBurstHistos.Add(hBkgNuCountProfile);
12710 }
12711 else if (mode.Contains("Bkg")) // Only renew in case of a new Background energy profile
12712 {
12713 hBkgNuCountProfile->Reset();
12714 hBkgNuCountProfile->SetBins(nebins,emin,emax,nabins,amin,amax);
12715 hBkgNuCountProfile->SetTitle(title);
12716 }
12717
12718 for (Int_t abin=1; abin<=nabins; abin++) // Loop over the cos(theta) bins
12719 {
12720 for (Int_t ebin=1; ebin<=nebins; ebin++) // Loop over the energy bins of hAeffProfile for this theta bin
12721 {
12722 xlow=xaxis->GetBinLowEdge(ebin);
12723 xup=xaxis->GetBinUpEdge(ebin);
12724 xlow=pow(10,xlow);
12725 xup=pow(10,xup);
12726 if (xup<fEmin || xlow>fEmax) continue;
12727 if (xlow<fEmin && xup>fEmin) xlow=fEmin;
12728 if (xup>fEmax && xlow<fEmax) xup=fEmax;
12729 aeff=hAeffProfile->GetBinContent(ebin,abin);
12730 integral=fBkgEprofile.Integral(xlow,xup);
12731 count=aeff*integral;
12732 hBkgNuCountProfile->SetBinContent(ebin,abin,count);
12733 }
12734 }
12735
12736 // Create also the Zenith profile
12737 title="Projection of hBkgNuCountProfile;Cosine of the Zenith angle (#theta);Counts";
12738 if (mode.Contains("F")) title+=" s^{-1}";
12739 if (mode.Contains("I")) title+=" s^{-1} sr^{ -1}";
12740
12741 if (!hBkgZenithProfile)
12742 {
12743 hBkgZenithProfile=hBkgNuCountProfile->ProjectionY("hBkgZenithProfile");
12744 fBurstHistos.Add(hBkgZenithProfile);
12745 }
12746 else if (mode.Contains("Bkg")) // Only renew in case of a new Signal energy profile
12747 {
12748 delete hBkgZenithProfile;
12749 hBkgZenithProfile=hBkgNuCountProfile->ProjectionY("hBkgZenithProfile");
12750 }
12751 hBkgZenithProfile->SetTitle(title);
12752 }
12753}
12754
12755void NcAstrolab::GenBurstGCNdata(Int_t n,TString name,Bool_t scale)
12756{
12777
12778 // Retreive the needed parameters
12779 Int_t fNmaxsrc=TMath::Nint(fBurstParameters->GetSignal("Nmaxsrc"));
12780 Float_t fRAmin=fBurstParameters->GetSignal("RAmin");
12781 Float_t fRAmax=fBurstParameters->GetSignal("RAmax");
12782 Float_t fDeclmin=fBurstParameters->GetSignal("Declmin");
12783 Float_t fDeclmax=fBurstParameters->GetSignal("Declmax");
12784 Float_t fT90min=fBurstParameters->GetSignal("T90min");
12785 Float_t fT90max=fBurstParameters->GetSignal("T90max");
12786 Float_t fZmin=fBurstParameters->GetSignal("Zmin");
12787 Float_t fZmax=fBurstParameters->GetSignal("Zmax");
12788 Float_t fSigmamin=fBurstParameters->GetSignal("Sigmamin");
12789 Float_t fSigmamax=fBurstParameters->GetSignal("Sigmamax");
12790 Float_t fOmegaDecl=fBurstParameters->GetSignal("OmegaDecl");
12791 Int_t fDweight=TMath::Nint(fBurstParameters->GetSignal("Dweight"));
12792
12793 if (scale)
12794 {
12795 Double_t pi=acos(-1.);
12796 n=TMath::Nint(double(n)*fOmegaDecl/(4.*pi));
12797 }
12798
12799 // Internal statistics
12800 Int_t fNgrbs=GetNsignals(0);
12801
12802 // Get access to a redshift distribution to draw randomly redshifts
12803 TH1* zdist=GetBurstZdist("GenBurstGCNdata()",name);
12804
12805 // Get access to a T90 distribution to draw randomly T90 values
12806 TH1* t90dist=GetBurstT90dist("GenBurstGCNdata()",name);
12807
12808 // Get access to a 1-sigma position uncertainty distribution to draw randomly position uncertaintes
12809 TH1* sigmaposdist=GetBurstSigmaPosdist("GenBurstGCNdata()",name);
12810
12811 if (!zdist || !t90dist || !sigmaposdist)
12812 {
12813 cout << endl;
12814 cout << " *" << ClassName() << "::GenBurstGCNdata* A distribution for random values is missing." << endl;
12815 cout << endl;
12816 return;
12817 }
12818
12819 Float_t thlow=90.-fDeclmax; // Lower theta angle in overall Earth spherical coordinates (North Pole is theta=0)
12820 Float_t thup=90.-fDeclmin; // Upper theta angle in overall Earth spherical coordinates (North Pole is theta=0)
12821 Float_t phimin=fRAmin; // Minimal phi angle in overall Earth spherical coordinates
12822 Float_t phimax=fRAmax; // Maximal phi angle in overall Earth spherical coordinates
12823 if (thlow<0) thlow=0;
12824 if (thup>180) thup=180;
12825
12826 NcSignal* sx=0;
12827 NcPosition rgrb;
12828 Float_t t90grb=0;
12829 Float_t zgrb=0;
12830 Float_t sigmagrb=0;
12831 TString grbname;
12832 Double_t thetagrb,phigrb,ragrb,decgrb;
12833 Double_t d=0;
12834 Int_t ngen=0;
12835
12836 for (Int_t igrb=1; igrb<=n; igrb++)
12837 {
12838 if (fNmaxsrc>=0 && (fNgrbs+ngen)>=fNmaxsrc) break;
12839
12840 zgrb=-1;
12841 if (fabs(fZmin)==fZmax) zgrb=fZmax;
12842 while (zgrb<fabs(fZmin) || zgrb>fZmax)
12843 {
12844 zgrb=zdist->GetRandom();
12845 }
12846
12847 t90grb=-1;
12848 if (fabs(fT90min)==fT90max) t90grb=fT90max;
12849 while (t90grb<fabs(fT90min) || t90grb>fT90max)
12850 {
12851 t90grb=t90dist->GetRandom();
12852 t90grb=pow(float(10),t90grb);
12853 }
12854
12855 sigmagrb=-1;
12856 if (fabs(fSigmamin)==fSigmamax) sigmagrb=fSigmamax;
12857 while (sigmagrb<fabs(fSigmamin) || sigmagrb>fSigmamax)
12858 {
12859 sigmagrb=sigmaposdist->GetRandom();
12860 }
12861
12862 rgrb.SetPosition(1,0,0,"sph","deg");
12863 RandomPosition(rgrb,thlow,thup,phimin,phimax);
12864 thetagrb=rgrb.GetX(2,"sph","deg");
12865 phigrb=rgrb.GetX(3,"sph","deg");
12866
12867 grbname="Random-";
12868 grbname+=name;
12869 grbname+=igrb;
12870 grbname+="#";
12871 ragrb=phigrb;
12872 decgrb=90.-thetagrb;
12873 sx=SetSignal(1,ragrb,"deg",decgrb,"deg","equ",0,-1,"J",grbname);
12874
12875 if (!sx) continue;
12876
12877 ngen++;
12878
12879 sx->AddNamedSlot("T90");
12880 sx->SetSignal(t90grb,"T90");
12881 sx->AddNamedSlot("csigma");
12882 sx->SetSignal(sigmagrb,"csigma");
12883 sx->AddNamedSlot("z");
12884 sx->SetSignal(zgrb,"z");
12885 // Determine the distance weight for this burst and update the distance weight sum
12886 if (fDweight)
12887 {
12888 d=GetPhysicalDistance(zgrb,"Gpc");
12889 if (d>0)
12890 {
12891 sx->AddNamedSlot("Dweight");
12892 sx->SetSignal(1./pow(d,2),"Dweight");
12893 fBurstParameters->AddSignal(1./pow(d,2),"DweightSum");
12894 }
12895 }
12896 }
12897
12898 // Update internal statistics
12899 fNgrbs=GetNsignals(0);
12900 fBurstParameters->AddNamedSlot("Ngrbs");
12901 fBurstParameters->SetSignal(fNgrbs,"Ngrbs");
12902
12903 printf("\n *%-s::GenBurstGCNdata* %-i new generated bursts with name %-s were stored. \n",ClassName(),ngen,name.Data());
12904 printf(" Total number of stored bursts : %-i \n",fNgrbs);
12905}
12906
12907void NcAstrolab::MakeBurstZdist(TString file,TString tree,TString name,Int_t nb,Float_t zmin,Float_t zmax)
12908{
12940
12941 // The Tree containing the archival data
12942 TChain data(tree.Data());
12943 data.Add(file.Data());
12944
12945 Int_t nen=data.GetEntries();
12946 TLeaf* lx=data.FindLeaf(name.Data());
12947
12948 if (!nen || !lx)
12949 {
12950 cout << " *" << ClassName() << "::MakeBurstZdist* Missing information for tree variable:" << name << endl;
12951 cout << " of Tree:" << tree << " with " << nen << " entries in file:" << file << endl;
12952 return;
12953 }
12954
12955 // Create new distributions in case a redshift distribution is not yet present
12956 TH1* zdist=(TH1*)fBurstHistos.FindObject("hz");
12957 if (!zdist)
12958 {
12959 // Creation of the archival burst redshift histogram
12960 TH1F* hz=new TH1F("hz","Archival data of observed burst redshifts",nb,zmin,zmax);
12961 fBurstHistos.Add(hz);
12962 hz->GetXaxis()->SetTitle("Burst redshift");
12963 hz->GetYaxis()->SetTitle("Counts");
12964
12965 // Creation of the corresponding physical distance histo
12966 Float_t dmin=GetPhysicalDistance(zmin);
12967 Float_t dmax=GetPhysicalDistance(zmax);
12968 TH1F* hd=new TH1F("hd","Burst distances derived from the archival redshift data",nb,dmin,dmax);
12969 fBurstHistos.Add(hd);
12970 hd->GetXaxis()->SetTitle("Burst physical distance in Mpc");
12971 hd->GetYaxis()->SetTitle("Counts");
12972 }
12973
12974 // Get pointers to the relevant histograms
12975 TH1* hz=(TH1*)fBurstHistos.FindObject("hz");
12976 TH1* hd=(TH1*)fBurstHistos.FindObject("hd");
12977
12978 Int_t nz=0;
12979 Double_t z=0;
12980 Double_t d=0;
12981 for (Int_t ien=0; ien<nen; ien++)
12982 {
12983 data.GetEntry(ien);
12984
12985 lx=data.GetLeaf(name.Data());
12986 if (!lx) continue;
12987
12988 z=lx->GetValue();
12989 if (z<zmin || z>zmax) continue;
12990
12991 hz->Fill(z);
12992 nz++;
12993
12995 hd->Fill(d);
12996 }
12997
12998 cout << " *" << ClassName() << "::MakeBurstZdist* " << nz << " archival z-values have been obtained from tree variable:" << name
12999 << " of Tree:" << tree << " in file(s):" << file << endl;
13000}
13001
13002TH1* NcAstrolab::GetBurstZdist(TString name,TString type)
13003{
13012
13013 TH1* zdist=(TH1*)fBurstHistos.FindObject("hz");
13014 if (!zdist)
13015 {
13016 if (type.Contains("GRB"))
13017 {
13018 cout << endl;
13019 cout << " *" << ClassName() << "::GetBurstZdist* Called from " << name << endl;
13020 cout << " *** Archival observed redshift distribution not found. ***" << endl;
13021 cout << " A Landau fit from Swift GRB redshift data will be used to provide missing c.q. random z values." << endl;
13022
13023 zdist=(TH1*)fBurstHistos.FindObject("hZpdf");
13024 if (!zdist)
13025 {
13026 TF1 fz("fz","59.54*TMath::Landau(x,1.092,0.5203)");
13027 fz.SetRange(0,10);
13028 fz.SetNpx(10000);
13029 TH1* hfz=fz.GetHistogram();
13030 zdist=(TH1*)hfz->Clone();
13031 zdist->SetNameTitle("hZpdf","Landau fit for Swift GRB z data");
13032 zdist->GetXaxis()->SetTitle("GRB redshift");
13033 zdist->GetYaxis()->SetTitle("Counts");
13034 fBurstHistos.Add(zdist);
13035 }
13036 }
13037 else // Source class for which no fit is available
13038 {
13039 cout << endl;
13040 cout << " *" << ClassName() << "::GetBurstZdist* Called from " << name << endl;
13041 cout << " *** No redshift fit is available for source class " << type << " ***" << endl;
13042 }
13043 }
13044
13045 return zdist;
13046}
13047
13048void NcAstrolab::MakeBurstT90dist(TString file,TString tree,TString name,Int_t nb,Float_t xmin,Float_t xmax)
13049{
13079
13080 // The Tree containing the burst data
13081 TChain data(tree.Data());
13082 data.Add(file.Data());
13083
13084 Int_t nen=data.GetEntries();
13085 TLeaf* lx=data.FindLeaf(name.Data());
13086
13087 if (!nen || !lx)
13088 {
13089 cout << " *" << ClassName() << "::MakeBurstT90dist* Missing information for tree variable:" << name << endl;
13090 cout << " of Tree:" << tree << " with " << nen << " entries in file:" << file << endl;
13091 return;
13092 }
13093
13094 // Create a new distribution in case a T90 distribution is not yet present
13095 TH1* t90dist=(TH1*)fBurstHistos.FindObject("ht90");
13096 if (!t90dist)
13097 {
13098 // Creation of observed burst t90 duration histo
13099 TH1F* ht90=new TH1F("ht90","Archival data of observed burst durations",nb,xmin,xmax);
13100 fBurstHistos.Add(ht90);
13101 ht90->GetXaxis()->SetTitle("Burst duration ^{10}log(T90) in sec.");
13102 ht90->GetYaxis()->SetTitle("Counts");
13103 }
13104
13105 // Get pointer to the relevant histogram
13106 TH1* ht90=(TH1*)fBurstHistos.FindObject("ht90");
13107
13108 Int_t nt90=0;
13109 Double_t t90=0;
13110 for (Int_t ien=0; ien<nen; ien++)
13111 {
13112 data.GetEntry(ien);
13113
13114 lx=data.GetLeaf(name.Data());
13115 if (!lx) continue;
13116
13117 t90=lx->GetValue();
13118 if (t90>0)
13119 {
13120 ht90->Fill(log10(t90));
13121 nt90++;
13122 }
13123 }
13124
13125 cout << " *" << ClassName() << "::MakeBurstT90dist* " << nt90 << " archival T90 values have been obtained from variable:" << name
13126 << " of Tree:" << tree << " in file(s):" << file << endl;
13127}
13128
13129TH1* NcAstrolab::GetBurstT90dist(TString name,TString type)
13130{
13139
13140 TH1* t90dist=(TH1*)fBurstHistos.FindObject("ht90");
13141 if (!t90dist)
13142 {
13143 if (type.Contains("GRB"))
13144 {
13145 cout << endl;
13146 cout << " *" << ClassName() << "::GetBurstT90dist* Called from " << name << endl;
13147 cout << " *** Observational T90 distribution not found. ***" << endl;
13148 cout << " A double Gaussian fit from Fermi GRB T90 data will be used to provide missing c.q. random T90 values." << endl;
13149
13150 t90dist=(TH1*)fBurstHistos.FindObject("hT90pdf");
13151 if (!t90dist)
13152 {
13153 TF1 ft("ft","44.39*TMath::Gaus(x,-0.131,0.481)+193.8*TMath::Gaus(x,1.447,0.4752)");
13154 ft.SetRange(-5,5);
13155 ft.SetNpx(10000);
13156 TH1* hft=ft.GetHistogram();
13157 t90dist=(TH1*)hft->Clone();
13158 t90dist->SetNameTitle("hT90pdf","Double Gauss fit for Fermi t90 data");
13159 t90dist->GetXaxis()->SetTitle("GRB duration ^{10}log(T90) in sec.");
13160 t90dist->GetYaxis()->SetTitle("Counts");
13161 fBurstHistos.Add(t90dist);
13162 }
13163 }
13164 else // Source class for which no fit is available
13165 {
13166 cout << endl;
13167 cout << " *" << ClassName() << "::GetBurstT90dist* Called from " << name << endl;
13168 cout << " *** No T90 fit is available for source class " << type << " ***" << endl;
13169 }
13170 }
13171
13172 return t90dist;
13173}
13174
13175void NcAstrolab::MakeBurstSigmaPosdist(TString file,TString tree,TString name,TString u,Int_t nb,Float_t xmin,Float_t xmax)
13176{
13215
13216 // The Tree containing the burst data
13217 TChain data(tree.Data());
13218 data.Add(file.Data());
13219
13220 Int_t nen=data.GetEntries();
13221 TLeaf* lx=data.FindLeaf(name.Data());
13222
13223 if (!nen || !lx)
13224 {
13225 cout << " *" << ClassName() << "::MakeBurstSigmaPosdist* Missing information for tree variable:" << name << endl;
13226 cout << " of Tree:" << tree << " with " << nen << " entries in file:" << file << endl;
13227 return;
13228 }
13229
13230 // Create a new distribution in case a burst position uncertainty distribution is not yet present
13231 TH1* sigmaposdist=(TH1*)fBurstHistos.FindObject("hsigmapos");
13232 if (!sigmaposdist)
13233 {
13234 // Creation of observed 1-sigma burst position uncertainty histo
13235 TH1F* hsigmapos=new TH1F("hsigmapos","Archival data of observed 1-sigma burst position uncertainties",nb,xmin,xmax);
13236 fBurstHistos.Add(hsigmapos);
13237 hsigmapos->GetXaxis()->SetTitle("Burst position uncertainty (sigma in degrees)");
13238 hsigmapos->GetYaxis()->SetTitle("Counts");
13239 }
13240
13241 // Get pointer to the relevant histogram
13242 TH1* hsigmapos=(TH1*)fBurstHistos.FindObject("hsigmapos");
13243
13244 Int_t nsigmapos=0;
13245 Double_t sigmapos=0;
13246 for (Int_t ien=0; ien<nen; ien++)
13247 {
13248 data.GetEntry(ien);
13249
13250 lx=data.GetLeaf(name.Data());
13251 if (!lx) continue;
13252
13253 sigmapos=lx->GetValue();
13254
13255 // Convert declination to degrees if needed
13256 sigmapos=ConvertAngle(sigmapos,u,"deg");
13257
13258 if (sigmapos<xmin || sigmapos>xmax) continue;
13259
13260 hsigmapos->Fill(sigmapos);
13261 nsigmapos++;
13262 }
13263
13264 cout << " *" << ClassName() << "::MakeBurstSigmaPosdist* " << nsigmapos << " archival sigmapos values have been obtained from variable:" << name
13265 << " of Tree:" << tree << " in file(s):" << file << endl;
13266}
13267
13268TH1* NcAstrolab::GetBurstSigmaPosdist(TString name,TString type)
13269{
13278
13279 TH1* sigmaposdist=(TH1*)fBurstHistos.FindObject("hsigmapos");
13280 if (!sigmaposdist)
13281 {
13282 if (type.Contains("GRB"))
13283 {
13284 cout << endl;
13285 cout << " *" << ClassName() << "::GetBurstSigmaPosdist* Called from " << name << endl;
13286 cout << " *** Archival observed GRB position uncertainty distribution not found. ***" << endl;
13287 cout << " A Landau fit from observed GRB data will be used to provide missing c.q. random 1-sigma uncertainty values." << endl;
13288
13289 sigmaposdist=(TH1*)fBurstHistos.FindObject("hSigmaSourcePDF");
13290 if (!sigmaposdist)
13291 {
13292 TF1 fsigmapos("fsigmapos","245.2*TMath::Landau(x,-2.209,0.6721,1)");
13293 fsigmapos.SetRange(0,90);
13294 fsigmapos.SetNpx(10000);
13295 TH1* hfsigmapos=fsigmapos.GetHistogram();
13296 sigmaposdist=(TH1*)hfsigmapos->Clone();
13297 sigmaposdist->SetNameTitle("hSigmaSourcePDF","Landau fit for burst 1-sigma position uncertainty data");
13298 sigmaposdist->GetXaxis()->SetTitle("Burst position uncertainty (sigma in degrees)");
13299 sigmaposdist->GetYaxis()->SetTitle("Counts");
13300 fBurstHistos.Add(sigmaposdist);
13301 }
13302 }
13303 else // Source class for which no fit is available
13304 {
13305 cout << endl;
13306 cout << " *" << ClassName() << "::GetBurstSigmaPosdist* Called from " << name << endl;
13307 cout << " *** No position uncertainty fit is available for source class " << type << " ***" << endl;
13308 }
13309 }
13310
13311 return sigmaposdist;
13312}
13313
13314void NcAstrolab::MakeBurstEnergydist(TString mode,TF1& spec,Int_t nsrc,Int_t nbins,Float_t Tem)
13315{
13407
13408 if (mode!="SigE" && mode!="SigS" && mode!="SigF" && mode!="SigI" && mode!="BkgE" && mode!="BkgS" && mode!="BkgF" && mode!="BkgI")
13409 {
13410 printf("\n *%-s::MakeBurstEnergydist* Inconsistent mode : %-s \n",ClassName(),mode.Data());
13411 printf(" The default energy PDF will be used \n");
13412 return;
13413 }
13414
13415 // Set the corresponding energy boudaries
13416 Float_t fESigmin=fBurstParameters->GetSignal("ESigmin");
13417 Float_t fESigmax=fBurstParameters->GetSignal("ESigmax");
13418 Float_t fEmin=fBurstParameters->GetSignal("Emin");
13419 Float_t fEmax=fBurstParameters->GetSignal("Emax");
13420
13421 Float_t Emin=0;
13422 Float_t Emax=0;
13423 if (mode.Contains("Sig"))
13424 {
13425 Emin=fESigmin;
13426 Emax=fESigmax;
13427 }
13428 else
13429 {
13430 Emin=fEmin;
13431 Emax=fEmax;
13432 }
13433
13434 if (Emin<=0) Emin=1e-10;
13435
13436 // For background spectra and mode="SigE" the value of nsrc is irrelevant
13437 if (mode.Contains("Bkg") || mode=="SigE") nsrc=1;
13438
13439 if (Emax<=Emin || nbins<1 || nsrc<1)
13440 {
13441 printf("\n *%-s::MakeBurstEnergydist* Inconsistent data : mode=%-s nsrc=%-i Emin=%-g Emax=%-g nbins=%-i \n",ClassName(),mode.Data(),nsrc,Emin,Emax,nbins);
13442 printf(" The default energy PDF will be used \n");
13443 return;
13444 }
13445
13446 // Convert the energy boundaries to the log10 scale of the X-axis
13447 Double_t xmin=log10(Emin);
13448 Double_t xmax=log10(Emax);
13449
13450 // Obtain the automatic Tem/Tobs scaling if needed
13451 Float_t fTfact=fBurstParameters->GetSignal("Tfact");
13452 Float_t fDtwin=fBurstParameters->GetSignal("Dtwin");
13453 Float_t fDtnus=fBurstParameters->GetSignal("Dtnus");
13454 Float_t Tobs=fDtwin*fTfact;
13455 if (Tem>0) Tem=Tem*fDtnus;
13456
13457 TString sf="";
13458 if (nsrc>1 && (mode=="SigS" || mode=="BkgS")) // Normalize the Fluence to a single source
13459 {
13460 sf.Form("(1./%-i)*%-s",nsrc,(spec.GetExpFormula("p")).Data());
13461 }
13462 else if (Tobs>0 && Tem>0 && (mode=="SigF" || mode=="SigI")) // Flux c.q. Intensity normalisation via Tem/Tobs
13463 {
13464 sf.Form("%-g*%-s",Tem/Tobs,(spec.GetExpFormula("p")).Data());
13465 }
13466 else
13467 {
13468 sf=spec.GetExpFormula("p");
13469 }
13470
13471 // The spectral function for each individual source
13472 TF1 spec2("spec2",sf);
13473
13474 // Store the normalized spectral function
13475 if (mode.Contains("Sig")) fSigEprofile=spec2;
13476 if (mode.Contains("Bkg")) fBkgEprofile=spec2;
13477
13478 Float_t norm=1;
13479 if (mode=="SigE" || mode=="BkgE")
13480 {
13481 sf="PDF for dN/dE=";
13482 sf+=spec2.GetExpFormula("p");
13483 norm=spec2.Integral(xmin,xmax);
13484 }
13485 else
13486 {
13487 sf="N cm^{-2}";
13488 if (mode.Contains("F")) sf+=" s^{-1}";
13489 if (mode.Contains("I")) sf+=" s^{-1} sr^{ -1}";
13490 sf+=" for dN/dE=";
13491 sf+=spec2.GetExpFormula("p");
13492 }
13493 sf.ReplaceAll("x","E");
13494 TString sh="";
13495 if (mode.Contains("Bkg")) sh="Isotropic background energy distribution at Earth";
13496 if (mode.Contains("Sig"))
13497 {
13498 if (mode=="SigE")
13499 {
13500 sh="Induced signal energy distribution at the source";
13501 }
13502 else
13503 {
13504 sh="Average per source induced signal energy distribution at Earth";
13505 }
13506 }
13507 sh+=";^{10}log(E/1GeV);";
13508 sh+=sf;
13509 TH1F his=GetCountsHistogram(spec2,nbins,xmin,xmax,1,sh);
13510
13511 // Remove the corresponding old distribution (if any) from the storage
13512 TH1* dist=0;
13513 if (mode.Contains("Bkg")) dist=(TH1*)fBurstHistos.FindObject("hBkgEprofile");
13514 if (mode.Contains("Sig")) dist=(TH1*)fBurstHistos.FindObject("hSigEprofile");
13515 if (dist)
13516 {
13517 fBurstHistos.Remove(dist);
13518 fBurstHistos.Compress();
13519 delete dist;
13520 dist=0;
13521 }
13522
13523 // Store the newly created distribution
13524 // and set a flag to indicate a parametrized distribution
13525 if (mode.Contains("Bkg"))
13526 {
13527 fBkgEmode=mode;
13528 TH1F* hBkgEprofile=(TH1F*)his.Clone("hBkgEprofile");
13529 if (mode=="BkgE") hBkgEprofile->Scale(1./norm);
13530 fBurstHistos.Add(hBkgEprofile);
13531 fBurstParameters->AddNamedSlot("PDFbkgE");
13532 fBurstParameters->SetSignal(1,"PDFbkgE");
13533 }
13534 if (mode.Contains("Sig"))
13535 {
13536 fSigEmode=mode;
13537 TH1F* hSigEprofile=(TH1F*)his.Clone("hSigEprofile");
13538 if (mode=="SigE") hSigEprofile->Scale(1./norm);
13539 fBurstHistos.Add(hSigEprofile);
13540 fBurstParameters->AddNamedSlot("PDFsigE");
13541 fBurstParameters->SetSignal(1,"PDFsigE");
13542 }
13543
13544 printf("\n *%-s::MakeBurstEnergydist* Per source %-s profile %-s on [Emin,Emax]=[%-g,%-g] GeV \n",ClassName(),mode.Data(),sf.Data(),Emin,Emax);
13545
13546 // Create the corresponding NuCount and Zenith profile by using the Effective Area data (if any)
13548}
13549
13550void NcAstrolab::MakeBurstEnergydist(TString mode,Double_t alpha,Int_t nbins)
13551{
13585
13586 if (mode!="SigE" && mode!="BkgE")
13587 {
13588 printf(" *%-s::MakeBurstEnergydist* Unsupported mode : %-s for only spectral index specification \n",ClassName(),mode.Data());
13589 return;
13590 }
13591
13592 TF1 spec("spec","pow(x,[0])");
13593 spec.SetParameter(0,-alpha);
13594 MakeBurstEnergydist(mode,spec,0,nbins);
13595}
13596
13597void NcAstrolab::MakeBurstEnergydist(Int_t mode,TString file,TString tree,TString name1,TString name2,TString u,Int_t nb)
13598{
13655
13656 Float_t fDeclmin=fBurstParameters->GetSignal("Declmin");
13657 Float_t fDeclmax=fBurstParameters->GetSignal("Declmax");
13658
13659 Float_t fESigmin=fBurstParameters->GetSignal("ESigmin");
13660 Float_t fESigmax=fBurstParameters->GetSignal("ESigmax");
13661 Float_t fEmin=fBurstParameters->GetSignal("Emin");
13662 Float_t fEmax=fBurstParameters->GetSignal("Emax");
13663
13664 Float_t Emin=0;
13665 Float_t Emax=0;
13666 if (abs(mode)==2)
13667 {
13668 Emin=fESigmin;
13669 Emax=fESigmax;
13670 }
13671 else
13672 {
13673 Emin=fEmin;
13674 Emax=fEmax;
13675 }
13676
13677 if (Emin<=0) Emin=1e-10;
13678
13679 if ((abs(mode)!=1 && abs(mode)!=2) || Emax<=Emin)
13680 {
13681 printf(" *%-s::MakeBurstEnergydist* Inconsistent data: mode=%-i Emin=%-g Emax=%-g \n",ClassName(),mode,Emin,Emax);
13682 return;
13683 }
13684
13685 // Convert the energy boundaries to the log10 scale of the X-axis
13686 Double_t xmin=log10(Emin);
13687 Double_t xmax=log10(Emax);
13688
13689 // The Tree containing the burst data
13690 TChain data(tree.Data());
13691 data.Add(file.Data());
13692
13693 Int_t nen=data.GetEntries();
13694
13695 if (!nen || !data.FindLeaf(name1.Data()) || !data.FindLeaf(name2.Data()))
13696 {
13697 cout << " *" << ClassName() << "::MakeBurstEnergydist* Missing information for tree variable:" << name1
13698 << " and/or tree variable:" << name2 << endl;
13699 cout << " of Tree:" << tree << " with " << nen << " entries in file:" << file << endl;
13700 return;
13701 }
13702
13703 // A corresponding parametrized distribution will always be removed
13704 Int_t flag=0;
13705 if (abs(mode)==1) flag=TMath::Nint(fBurstParameters->GetSignal("PDFbkgE"));
13706 if (abs(mode)==2) flag=TMath::Nint(fBurstParameters->GetSignal("PDFsigE"));
13707
13708 if (flag) mode=abs(mode);
13709
13710 // Remove the corresponding old distribution (if requested) from the storage
13711 TH1* Edist=0;
13712 if (abs(mode)==1) Edist=(TH1*)fBurstHistos.FindObject("hBkgEprofile");
13713 if (abs(mode)==2) Edist=(TH1*)fBurstHistos.FindObject("hSigEprofile");
13714
13715 if (mode>0 && Edist)
13716 {
13717 fBurstHistos.Remove(Edist);
13718 fBurstHistos.Compress();
13719 delete Edist;
13720 Edist=0;
13721 }
13722
13723 // Create a new distribution if needed
13724 if (!Edist)
13725 {
13726 mode=abs(mode);
13727 if (mode==1)
13728 {
13729 // Creation of the observed background energy histo
13730 fBkgEmode="BkgE";
13731 TH1F* hBkgEprofile=new TH1F("hBkgEprofile","Archival data of observed background energies",nb,xmin,xmax);
13732 fBurstHistos.Add(hBkgEprofile);
13733 hBkgEprofile->GetXaxis()->SetTitle("^{10}log(Energy) in GeV");
13734 hBkgEprofile->GetYaxis()->SetTitle("Counts");
13735 fBurstParameters->AddNamedSlot("PDFbkgE");
13736 fBurstParameters->SetSignal(0,"PDFbkgE");
13737 }
13738 if (mode==2)
13739 {
13740 // Creation of the observed signal energy histo
13741 fSigEmode="SigE";
13742 TH1F* hSigEprofile=new TH1F("hSigEprofile","Archival data of observed signal energies",nb,xmin,xmax);
13743 fBurstHistos.Add(hSigEprofile);
13744 hSigEprofile->GetXaxis()->SetTitle("^{10}log(Energy) in GeV");
13745 hSigEprofile->GetYaxis()->SetTitle("Counts");
13746 fBurstParameters->AddNamedSlot("PDFsigE");
13747 fBurstParameters->SetSignal(0,"PDFsigE");
13748 fBurstParameters->SetSignal(0,"Ezcor");
13749 }
13750 }
13751
13752 // Get pointer to the relevant histogram
13753 if (abs(mode)==1) Edist=(TH1*)fBurstHistos.FindObject("hBkgEprofile");
13754 if (abs(mode)==2) Edist=(TH1*)fBurstHistos.FindObject("hSigEprofile");
13755
13756 Int_t nE=0;
13757 Double_t logE=0;
13758 Double_t dec=0;
13759 TLeaf* lx=0;
13760 for (Int_t ien=0; ien<nen; ien++)
13761 {
13762 data.GetEntry(ien);
13763
13764 lx=data.GetLeaf(name1.Data());
13765 if (!lx) continue;
13766
13767 logE=lx->GetValue();
13768
13769 lx=data.GetLeaf(name2.Data());
13770 if (!lx) continue;
13771
13772 dec=lx->GetValue();
13773
13774 // Convert declination to degrees if needed
13775 dec=ConvertAngle(dec,u,"deg");
13776
13777 if (dec>=fDeclmin && dec<=fDeclmax)
13778 {
13779 Edist->Fill(logE);
13780 nE++;
13781 }
13782 }
13783
13784 TString smode="";
13785 if (abs(mode)==1) smode="archival background";
13786 if (abs(mode)==2) smode="archival signal";
13787
13788 if (mode>0)
13789 {
13790 cout << " *" << ClassName() << "::MakeBurstEnergydist* A new " << smode
13791 << " energy distribution has been created." << endl;
13792 }
13793 else
13794 {
13795 cout << " *" << ClassName() << "::MakeBurstEnergydist* Statistics of the existing " << smode
13796 << " energy distribution have been increased." << endl;
13797 }
13798
13799 cout << " " << nE << " energy values have been obtained from variable:" << name1
13800 << " of Tree:" << tree << " in file(s):" << file << endl;
13801}
13802
13803void NcAstrolab::MakeBurstRecoAngresdist(TString file,TString tree,TString name1,TString name2,TString ua,TString name3,TString ud,Double_t Emin,Double_t Emax,Int_t nbe,Int_t nba)
13804{
13852
13853 Float_t fDeclmin=fBurstParameters->GetSignal("Declmin");
13854 Float_t fDeclmax=fBurstParameters->GetSignal("Declmax");
13855
13856 if (Emin<=0) Emin=1e-10;
13857
13858 if (Emax<=Emin)
13859 {
13860 cout << " *" << ClassName() << "::MakeBurstRecoAngresdist* Inconsistent data: Emin=" << Emin << " Emax=" << Emax << endl;
13861 return;
13862 }
13863
13864 // Convert the energy boundaries to the log10 scale of the X-axis
13865 Double_t xmin=log10(Emin);
13866 Double_t xmax=log10(Emax);
13867
13868 // The Tree containing the burst data
13869 TChain data(tree.Data());
13870 data.Add(file.Data());
13871
13872 Int_t nen=data.GetEntries();
13873
13874 if (!nen || !data.FindLeaf(name1.Data()) || !data.FindLeaf(name2.Data()) || !data.FindLeaf(name3.Data()))
13875 {
13876 cout << " *" << ClassName() << "::MakeBurstRecoAngresdist* Missing information for tree variable:" << name1
13877 << " and/or tree variable:" << name2 << " and/or tree variable:" << name3 << endl;
13878 cout << " of Tree:" << tree << " with " << nen << " entries in file:" << file << endl;
13879 return;
13880 }
13881
13882 // Create a new distribution in case a reconstruction angle resolution vs. energy distribution is not yet present
13883 TH2* Angresdist=(TH2*)fBurstHistos.FindObject("hAngresE");
13884 if (!Angresdist)
13885 {
13886 // Creation of the observed reconstruction angle resolution vs. energy histo
13887 TH2F* hAngresE=new TH2F("hAngresE","Archival data of observed reconstruction angle resolution vs. energy",
13888 nbe,xmin,xmax,nba,0,180.1);
13889 fBurstHistos.Add(hAngresE);
13890 hAngresE->GetXaxis()->SetTitle("^{10}log(Energy) in GeV");
13891 hAngresE->GetYaxis()->SetTitle("Angular resolution in degrees");
13892 }
13893
13894 // Get pointer to the relevant histogram
13895 TH2* hAngresE=(TH2*)fBurstHistos.FindObject("hAngresE");
13896
13897 Int_t nE=0;
13898 Double_t logE=0;
13899 Double_t dec=0;
13900 Double_t dang=0;
13901 TLeaf* lx=0;
13902 for (Int_t ien=0; ien<nen; ien++)
13903 {
13904 data.GetEntry(ien);
13905
13906 lx=data.GetLeaf(name1.Data());
13907 if (!lx) continue;
13908
13909 logE=lx->GetValue();
13910
13911 lx=data.GetLeaf(name2.Data());
13912 if (!lx) continue;
13913
13914 dang=lx->GetValue();
13915
13916 // Convert declination to degrees if needed
13917 dang=ConvertAngle(dang,ua,"deg");
13918
13919 lx=data.GetLeaf(name3.Data());
13920 if (!lx) continue;
13921
13922 dec=lx->GetValue();
13923
13924 // Convert declination to degrees if needed
13925 dec=ConvertAngle(dec,ud,"deg");
13926
13927 if (dec>=fDeclmin && dec<=fDeclmax)
13928 {
13929 hAngresE->Fill(logE,dang);
13930 nE++;
13931 }
13932 }
13933
13934 cout << " *" << ClassName() << "::MakeBurstRecoAngresdist* " << nE << " archival entries have been obtained for variables:" << name2
13935 << " vs. " << name1 << " of Tree:" << tree << " in file(s):" << file << endl;
13936}
13937
13938Double_t NcAstrolab::GetBurstSignalEnergy(Double_t Emin,Double_t Emax) const
13939{
13957
13958 Double_t E=-1;
13959
13960 // Get pointer to the relevant histogram
13961 TH1* hSigEprofile=(TH1*)fBurstHistos.FindObject("hSigEprofile");
13962
13963 if (!hSigEprofile) return E;
13964
13965 Int_t nbins=hSigEprofile->GetNbinsX();
13966 Int_t nentries=hSigEprofile->GetEntries();
13967
13968 if (nbins<=0 || nentries<=0) return E;
13969
13970 TAxis* xaxis=hSigEprofile->GetXaxis();
13971
13972 if (!xaxis) return E;
13973
13974 Double_t xlow=xaxis->GetBinLowEdge(1);
13975 Double_t xup=xaxis->GetBinUpEdge(nbins);
13976
13977 Double_t logEmin=0;
13978 if (Emin<=0)
13979 {
13980 logEmin=xlow;
13981 }
13982 else
13983 {
13984 logEmin=log10(Emin);
13985 }
13986
13987 Double_t logEmax=0;
13988 if (Emax<=0)
13989 {
13990 logEmax=xup;
13991 }
13992 else
13993 {
13994 logEmax=log10(Emax);
13995 }
13996
13997 if (logEmax<=logEmin || logEmin>=xup || logEmax<=xlow) return E;
13998
13999 while (E<logEmin || E>logEmax)
14000 {
14001 E=hSigEprofile->GetRandom();
14002 }
14003
14004 E=pow(float(10),E);
14005
14006 return E;
14007}
14008
14009Double_t NcAstrolab::GetBurstBackgroundEnergy(Double_t Emin,Double_t Emax) const
14010{
14028
14029 Double_t E=-1;
14030
14031 // Get pointer to the relevant histogram
14032 TH1* hBkgEprofile=(TH1*)fBurstHistos.FindObject("hBkgEprofile");
14033
14034 if (!hBkgEprofile) return E;
14035
14036 Int_t nbins=hBkgEprofile->GetNbinsX();
14037 Int_t nentries=hBkgEprofile->GetEntries();
14038
14039 if (nbins<=0 || nentries<=0) return E;
14040
14041 TAxis* xaxis=hBkgEprofile->GetXaxis();
14042
14043 if (!xaxis) return E;
14044
14045 Double_t xlow=xaxis->GetBinLowEdge(1);
14046 Double_t xup=xaxis->GetBinUpEdge(nbins);
14047
14048 Double_t logEmin=0;
14049 if (Emin<=0)
14050 {
14051 logEmin=xlow;
14052 }
14053 else
14054 {
14055 logEmin=log10(Emin);
14056 }
14057
14058 Double_t logEmax=0;
14059 if (Emax<=0)
14060 {
14061 logEmax=xup;
14062 }
14063 else
14064 {
14065 logEmax=log10(Emax);
14066 }
14067
14068 if (logEmax<=logEmin || logEmin>=xup || logEmax<=xlow) return E;
14069
14070 while (E<logEmin || E>logEmax)
14071 {
14072 E=hBkgEprofile->GetRandom();
14073 }
14074
14075 E=pow(float(10),E);
14076
14077 return E;
14078}
14079
14080Double_t NcAstrolab::GetBurstRecoAngres(Double_t Emin,Double_t Emax,Double_t Amin,Double_t Amax) const
14081{
14105
14106 Double_t dang=-1;
14107
14108 if (Amin<0) Amin=0;
14109
14110 Int_t fRecoangle=TMath::Nint(fBurstParameters->GetSignal("Recoangle"));
14111 Float_t fAngresfix=fBurstParameters->GetSignal("Angresfix");
14112
14113 // The user requested a fixed angular resolution value "Angresfix"
14114 if (!fRecoangle)
14115 {
14116 dang=fAngresfix;
14117 return dang;
14118 }
14119
14120 // The user requested an angular resolution based on a distribution
14121
14122 // Get pointer to the reco angle resolution vs. energy distribution histogram
14123 TH2* hAngresE=(TH2*)fBurstHistos.FindObject("hAngresE");
14124
14125 // No distribution available -> Return the user provided "Angresfix" value
14126 if (!hAngresE)
14127 {
14128 dang=fAngresfix;
14129 return dang;
14130 }
14131
14132 // Obtain the projected reco angle resolution distribution within the [Emin,Emax] interval
14133
14134 Int_t nbins=hAngresE->GetNbinsX();
14135 Int_t nentries=hAngresE->GetEntries();
14136
14137 if (nbins<=0 || nentries<=0) return dang;
14138
14139 TAxis* xaxis=hAngresE->GetXaxis();
14140
14141 if (!xaxis) return dang;
14142
14143 Double_t xlow=xaxis->GetBinLowEdge(1);
14144 Double_t xup=xaxis->GetBinUpEdge(nbins);
14145
14146 Double_t logEmin=0;
14147 if (Emin<=0)
14148 {
14149 logEmin=xlow;
14150 }
14151 else
14152 {
14153 logEmin=log10(Emin);
14154 }
14155
14156 Double_t logEmax=0;
14157 if (Emax<=0)
14158 {
14159 logEmax=xup;
14160 }
14161 else
14162 {
14163 logEmax=log10(Emax);
14164 }
14165
14166 if (logEmax<logEmin || logEmin>=xup || logEmax<=xlow) return dang;
14167
14168 Int_t ilow=xaxis->FindBin(logEmin);
14169 Int_t iup=xaxis->FindBin(logEmax);
14170
14171 TH1D* hproj=hAngresE->ProjectionY("hproj",ilow,iup);
14172
14173 if (!hproj) return dang;
14174
14175 nbins=hproj->GetNbinsX();
14176 nentries=hproj->GetEntries();
14177
14178 if (nbins<=0 || nentries<=0) return dang;
14179
14180 if (fRecoangle==1) dang=hproj->GetMean();
14181
14182 if (fRecoangle==2)
14183 {
14184 NcSample q;
14185 dang=q.GetMedian(hproj);
14186 }
14187
14188 if (fRecoangle==3)
14189 {
14190 xaxis=hproj->GetXaxis();
14191
14192 if (!xaxis) return dang;
14193
14194 xlow=xaxis->GetBinLowEdge(1);
14195 xup=xaxis->GetBinUpEdge(nbins);
14196
14197 if (Amax<=Amin || Amin>=xup || Amax<=xlow) return dang;
14198
14199 dang=Amin-1.;
14200 while (dang<Amin || dang>Amax)
14201 {
14202 dang=hproj->GetRandom();
14203 }
14204 }
14205
14206 if (hproj) delete hproj;
14207
14208 return dang;
14209}
14210
14212{
14231
14232 // Indicate that this will be a burst analysis on simulated data
14233 fBurstParameters->AddNamedSlot("BurstDataMode");
14234 fBurstParameters->SetSignal(0,"BurstDataMode");
14235
14236 // Signal and background generation can only be performed for a user defined fixed time window size
14237 Float_t fTmin=fBurstParameters->GetSignal("Tmin");
14238 Float_t fTmax=fBurstParameters->GetSignal("Tmax");
14239 if (fTmax<=fTmin)
14240 {
14241 printf("\n *%-s::GenBurstSignals* Error : [Tmin,Tmax]=[%-g,%-g] whereas Tmin<Tmax is required. \n",ClassName(),fTmin,fTmax);
14242 return;
14243 }
14244
14245 // If needed, initialise the randomiser with a "date/time driven" seed
14246 // using the timestamp of the moment of this invokation of the member function.
14247 // This will ensure different random sequences if the user repeats analyses
14248 // with identical measurements and reference signals without explicit initialisation
14249 // of the randomiser by the user at the start of the analysis.
14250 if (!fRan) fRan=new NcRandom(-1);
14251
14253 // Initialise the final sample histograms //
14255
14257
14258 // Retrieve the needed parameters
14259 Float_t fRAmin=fBurstParameters->GetSignal("RAmin");
14260 Float_t fRAmax=fBurstParameters->GetSignal("RAmax");
14261 Float_t fDeclmin=fBurstParameters->GetSignal("Declmin");
14262 Float_t fDeclmax=fBurstParameters->GetSignal("Declmax");
14263 Float_t fOmegaDecl=fBurstParameters->GetSignal("OmegaDecl");
14264 Float_t fTimres=fBurstParameters->GetSignal("Timres");
14265 Int_t fEzcor=TMath::Nint(fBurstParameters->GetSignal("Ezcor"));
14266 Int_t fPDFsigE=TMath::Nint(fBurstParameters->GetSignal("PDFsigE"));
14267 Float_t fEmin=fBurstParameters->GetSignal("Emin");
14268 Float_t fEmax=fBurstParameters->GetSignal("Emax");
14269 Int_t fKinangle=TMath::Nint(fBurstParameters->GetSignal("Kinangle"));
14270 Float_t fAngresmin=fBurstParameters->GetSignal("Angresmin");
14271 Float_t fAngresmax=fBurstParameters->GetSignal("Angresmax");
14272 Float_t fAngresfix=fBurstParameters->GetSignal("Angresfix");
14273 Int_t fRecoangle=TMath::Nint(fBurstParameters->GetSignal("Recoangle"));
14274 Int_t fSumsigmas=TMath::Nint(fBurstParameters->GetSignal("Sumsigmas"));
14275 Float_t fTfact=fBurstParameters->GetSignal("Tfact");
14276 Float_t fDtwin=fBurstParameters->GetSignal("Dtwin");
14277 Float_t fDawin=fBurstParameters->GetSignal("Dawin");
14278 Int_t fDatype=TMath::Nint(fBurstParameters->GetSignal("Datype"));
14279 Float_t fGrbnu=fBurstParameters->GetSignal("Grbnu");
14280 Int_t fInburst=TMath::Nint(fBurstParameters->GetSignal("Inburst"));
14281 Float_t fDtnu=fBurstParameters->GetSignal("Dtnu");
14282 Float_t fDtnus=fBurstParameters->GetSignal("Dtnus");
14283 Int_t fNbkg=TMath::Nint(fBurstParameters->GetSignal("Nbkg"));
14284 Int_t fDweight=TMath::Nint(fBurstParameters->GetSignal("Dweight"));
14285 Float_t fDweightSum=fBurstParameters->GetSignal("DweightSum");
14286
14287 // Deactivate redshift correction for source signal events from archival observed data
14288 if (!fPDFsigE)
14289 {
14290 fEzcor=0;
14291 fBurstParameters->SetSignal(0,"Ezcor");
14292 }
14293
14294 // Derived parameters
14295 Float_t fMaxsigmatot=fBurstParameters->GetSignal("Maxsigmatot");
14296 Float_t fNbkgWin=fBurstParameters->GetSignal("NbkgWin");
14297
14299 // Some Burst statistics from the loaded data //
14301
14302 Int_t fNgrbs=GetNsignals(0);
14303
14304 TH1* hSigE=(TH1*)fBurstHistos.FindObject("hSigE");
14305 TH1* hSigEzcor=(TH1*)fBurstHistos.FindObject("hSigEzcor");
14306 TH2* hAeffProfile=(TH2*)fBurstHistos.FindObject("hAeffProfile");
14307 TH2* hSigNuCountProfile=(TH2*)fBurstHistos.FindObject("hSigNuCountProfile");
14308 TH2* hBkgNuCountProfile=(TH2*)fBurstHistos.FindObject("hBkgNuCountProfile");
14309
14311 // Generation of the signal and background observations //
14312 // based on the provided user settings //
14314
14315 NcSignal* sx=0;
14316 Float_t zgrb=0;
14317 Double_t dgrb=0;
14318 Float_t t90grb=0;
14319 Float_t sigmagrb=0;
14320 NcPosition rgrb;
14321 Float_t nbkg=0; // The mean number of recordable background events in the time window for the treated GRB
14322 Float_t nsig=0; // The mean number of recordable signal events for the treated GRB
14323 Float_t dweight=1; // Distance weight for the observed Fluence or Flux from the treated GRB
14324 Int_t nmu;
14325 Double_t thetagrb,phigrb;
14326 Double_t dmu,thetamu,phimu;
14327 Float_t dt=0;
14328 NcPosition rgrb2; // Unknown actual GRB position from which the neutrinos/muons arrive
14329 NcPosition rmu;
14330 Float_t dang;
14331 Float_t dangmax=0;
14332 Float_t dangmaxon=0;
14333 Float_t dangmaxoff=0;
14334 Float_t thlow,thup;
14335 Float_t ranlow,ranup;
14336 Int_t nmugrb=0;
14337 NcTimestamp* tx=0;
14338 NcTimestamp tmu;
14339 Float_t solidangle=0;
14340 Float_t ramu,decmu; // Temporary RA and DEC of muon for background creation
14341 Double_t E=0;
14342 Double_t ang=0;
14343 Double_t sigmareco=0;
14344 Float_t sigmatot=0;
14345 TString name;
14346 Int_t fixedwinset=0; // Flag to indicate whether a fixed angular search window is set (1) or not (0) for this burst
14347
14348 // Storage for total on-source and off-source observed and signal injected energies
14349 fBurstParameters->AddNamedSlot("EnergyOn");
14350 fBurstParameters->AddNamedSlot("EnergyOff");
14351 fBurstParameters->AddNamedSlot("EnergySig");
14352
14353 // The bin numbers and Aeff value in the AeffProfile for the (E,theta) of the track
14354 Int_t nbinsA=0;
14355 if (hAeffProfile) nbinsA=(hAeffProfile->GetNbinsX())*(hAeffProfile->GetNbinsY());
14356 Double_t Aeff=0;
14357 Double_t Fluence=0;
14358
14359 TAxis* xaxis=0;
14360 TAxis* yaxis=0;
14361 Int_t nbinsx=0;
14362 Int_t nbinsy=0;
14363 Int_t xbin=0;
14364 Int_t ybin=0;
14365 Int_t zbin=0;
14366 Int_t gbin=0; // The global bin number in the histogram
14367 Float_t LogElow=0;
14368 Float_t LogEup=0;
14369 Float_t elow=0;
14370 Float_t eup=0;
14371 Float_t CosZenlow=0;
14372 Float_t CosZenup=0;
14373 Float_t CosZen=0;
14374
14375 Double_t pi=acos(-1.);
14376
14377 // Loop over the (fictative) GRB space-time positions in the declination acceptance
14378 for (Int_t igrb=0; igrb<fNgrbs; igrb++)
14379 {
14380 sx=GetSignal(igrb+1);
14381
14382 if (!sx) continue;
14383
14384 tx=sx->GetTimestamp();
14385 zgrb=sx->GetSignal("z");
14386 t90grb=sx->GetSignal("T90");
14387 sigmagrb=sx->GetSignal("csigma");
14388
14389 dangmax=-1;
14390 if (!fDatype) dangmax=fabs(fDawin);
14391 if (fDatype==1)
14392 {
14393 dangmax=0;
14394 if (fMaxsigmatot>0) dangmax=fabs(fDawin*fMaxsigmatot);
14395 }
14396
14397 if (fDatype==2)
14398 {
14399 if (!fSumsigmas) dangmax=fabs(fDawin*sigmagrb);
14400 if (!fRecoangle)
14401 {
14402 sigmatot=-1;
14403 if (fSumsigmas==-1) sigmatot=fAngresfix;
14404 if (fSumsigmas==1) sigmatot=sigmagrb+fAngresfix;
14405 if (fSumsigmas==2) sigmatot=sqrt(sigmagrb*sigmagrb+fAngresfix*fAngresfix);
14406 if (sigmatot>=0) dangmax=fabs(fDawin*sigmatot);
14407 }
14408 }
14409
14410 fixedwinset=1;
14411 if (dangmax<0) fixedwinset=0;
14412
14413 // Indicate incompatible input for sigma summation
14414 if (fDatype==1 && fMaxsigmatot<0) dangmax=-1;
14415
14416 // New signal slots for storage of maximum angular differences and corresponding solid angles
14417 name="fixedwinset";
14418 sx->AddNamedSlot(name);
14419 sx->SetSignal(fixedwinset,name);
14420 name="dangmaxOn";
14421 sx->AddNamedSlot(name);
14422 sx->SetSignal(-1,name);
14423 name="dangmaxOff";
14424 sx->AddNamedSlot(name);
14425 sx->SetSignal(-1,name);
14426 name="OmegaOn";
14427 sx->AddNamedSlot(name);
14428 sx->SetSignal(0,name);
14429 name="OmegaOff";
14430 sx->AddNamedSlot(name);
14431 sx->SetSignal(0,name);
14432
14433 // Store the On-source and Off-source maximum (solid) angles for this burst
14434 if (fixedwinset && dangmax>=0)
14435 {
14436 if (fDawin<0) // Local zenith band centered at the GRB position at its trigger time
14437 {
14438 GetSignal(dgrb,thetagrb,"deg",phigrb,"deg","loc",tx,igrb+1);
14439 thlow=thetagrb-0.5*dangmax;
14440 thup=thetagrb+0.5*dangmax;
14441 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
14442 }
14443 else // Circle around GRB position
14444 {
14445 thlow=0;
14446 thup=dangmax;
14447 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
14448 }
14449 sx->SetSignal(dangmax,"dangmaxOn");
14450 sx->SetSignal(solidangle,"OmegaOn");
14451 sx->SetSignal(dangmax,"dangmaxOff");
14452 sx->SetSignal(solidangle*float(fNbkg),"OmegaOff");
14453 }
14454 else // Initialize the encountered dynamic On-source and Off-source maximum angles for this burst
14455 {
14456 dangmaxon=0;
14457 if (fSumsigmas==0 || fSumsigmas==1 || fSumsigmas==2) dangmaxon=fabs(fDawin*sigmagrb);
14458 dangmaxoff=dangmaxon;
14459 }
14460
14461 // Generate the background events in the search time window
14462 // for both this GRB angular cone and the corresponding background bkg patch(es)
14463 for (Int_t bkgpatch=0; bkgpatch<=fNbkg; bkgpatch++)
14464 {
14465
14466 if (fBkgEmode=="BkgE") // Background rate set via user provided burst parameter "Bkgrate"
14467 {
14468 nmu=int(fRan->Poisson(fNbkgWin)); // nmu is the number of backgound events in the time window
14469 // Use the full energy range as provided by the user
14470 elow=-1;
14471 eup=-1;
14472 nbkg=1;
14473 }
14474 else // Neutrino background strength set via user provided Fluence, Flux or Intensity
14475 {
14476 xaxis=0;
14477 yaxis=0;
14478 nbinsx=0;
14479 nbinsy=0;
14480 if (hBkgNuCountProfile)
14481 {
14482 xaxis=hBkgNuCountProfile->GetXaxis();
14483 yaxis=hBkgNuCountProfile->GetYaxis();
14484 nbinsx=xaxis->GetNbins();
14485 nbinsy=yaxis->GetNbins();
14486 }
14487 nmu=nbinsx*nbinsy; // nmu will loop over all the cos(theta) vs. energy bins
14488 }
14489
14490 for (Int_t imu=0; imu<nmu; imu++)
14491 {
14492 // Check for a possible background event in case a Fluence, Flux or Intensity was specified
14493 if (fBkgEmode!="BkgE" && hBkgNuCountProfile)
14494 {
14495 // Investigate whether one or more background events will result at this (energy,theta) location
14496 gbin=imu+1;
14497 nbkg=hBkgNuCountProfile->GetBinContent(gbin);
14498
14499 if (nbkg<=0) continue;
14500
14501 // Obtain the corresponding X-axis and Y-axis bins
14502 hBkgNuCountProfile->GetBinXYZ(gbin,xbin,ybin,zbin);
14503
14504 // Boundaries of this Log(energy) bin to provide a random energy below
14505 LogElow=xaxis->GetBinLowEdge(xbin);
14506 LogEup=xaxis->GetBinUpEdge(xbin);
14507 elow=pow(10,LogElow);
14508 eup=pow(10,LogEup);
14509
14510 // Boundaries of this cos(zenith) bin to provide a random theta below
14511 CosZenlow=yaxis->GetBinLowEdge(ybin);
14512 CosZenup=yaxis->GetBinUpEdge(ybin);
14513
14514 // A steady flux is assumed during the complete obervation time
14515 if (fBkgEmode!="BkgS") nbkg=nbkg*fDtwin*fTfact;
14516
14517 // An isotropic diffuse flux is assumed when an Intensity was specified
14518 if (fBkgEmode=="BkgI") nbkg=nbkg*fOmegaDecl;
14519
14520 // Allow Poisson fluctuations
14521 if (nbkg>0) nbkg=fRan->Poisson(nbkg);
14522 }
14523
14524 // Process all background events for this (energy,theta) location in the CountProfile
14525 // or just the next of "nmu" background events as provided via the burst parameter "Bkgrate"
14526 for (Int_t ibkg=0; ibkg<int(nbkg); ibkg++)
14527 {
14528 // The energy of the background signal
14529 E=GetBurstBackgroundEnergy(elow,eup);
14530
14531 if (E<0 || E<fEmin || E>fEmax) continue;
14532
14533 // Obtain a random event time within the search time window
14534 ranlow=fTmin;
14535 ranup=fTmax;
14536 dt=fRan->Uniform(ranlow,ranup);
14537 tmu=*tx;
14538 tmu.AddSec(dt*fTfact);
14539
14540 if (fBkgEmode=="BkgE")
14541 {
14542 // Create a random background event within the user selected burst RA and Dec interval
14543 // and convert to local detector coordinates.
14544 // For the conversion, a single, re-usable temp. reference signal will be created, since measurements may get scrambled when stored.
14545 thlow=90.-fDeclmax; // Lower theta angle in overall Earth spherical coordinates (North Pole is theta=0)
14546 thup=90.-fDeclmin; // Upper theta angle in overall Earth spherical coordinates (North Pole is theta=0)
14547 RandomPosition(rmu,thlow,thup,fRAmin,fRAmax);
14548 decmu=90.-rmu.GetX(2,"sph","deg");
14549 ramu=rmu.GetX(3,"sph","deg");
14550 SetSignal(1,ramu,"deg",decmu,"deg","equ",&tmu,fNgrbs+1,"J","bkgtemp",0);
14551 GetSignal(dmu,thetamu,"deg",phimu,"deg","loc",&tmu,fNgrbs+1);
14552 }
14553 else
14554 {
14555 // Create a background event in local coordinates at this cos(zenith) position
14556 CosZen=fRan->Uniform(CosZenlow,CosZenup);
14557 thetamu=acos(CosZen)*180./pi;
14558 phimu=fRan->Uniform(0.,2.*pi);
14559 }
14560
14561 rmu.SetPosition(1,thetamu,phimu,"sph","deg");
14562
14563 if (fDawin<0) // Local zenith band centered at the GRB position at its trigger time
14564 {
14565 dang=fabs(thetagrb-thetamu);
14566 }
14567 else // Circle around the GRB local position at the muon observation time
14568 {
14569 GetSignal(dgrb,thetagrb,"deg",phigrb,"deg","loc",&tmu,igrb+1);
14570 rgrb.SetPosition(1,thetagrb,phigrb,"sph","deg");
14571 dang=rgrb.GetOpeningAngle(rmu,"deg");
14572 }
14573
14574 // Check if event lies outside the allowed angular area
14575 if (fDatype>=0 && fixedwinset && dang>dangmax) continue;
14576
14577 // The reconstruction angular resolution of the background signal
14578 sigmareco=GetBurstRecoAngres(E,E);
14579 if (sigmareco<0) sigmareco=fAngresfix;
14580
14581 if (sigmareco<fAngresmin || sigmareco>fAngresmax) continue;
14582
14583 sigmatot=-1;
14584 if (fSumsigmas==-1) sigmatot=sigmareco;
14585 if (fSumsigmas==0) sigmatot=sigmagrb;
14586 if (fSumsigmas==1) sigmatot=sigmagrb+sigmareco;
14587 if (fSumsigmas==2) sigmatot=sqrt(sigmagrb*sigmagrb+sigmareco*sigmareco);
14588
14589 // Determine the dynamic angular window including the track reco uncertainty
14590 if (!fixedwinset)
14591 {
14592 dangmax=-1;
14593 if (sigmatot>=0) dangmax=fabs(fDawin*sigmatot);
14594 }
14595
14596 if (fDatype>=0 && dang>dangmax) continue;
14597
14598 if (!bkgpatch) // On-source patch
14599 {
14600 if (dangmax>dangmaxon) dangmaxon=dangmax;
14601 fBurstOnReco.Enter(zgrb,sigmagrb,sigmareco,sigmatot);
14602 fBurstOnMatch.Enter(E,dt,dang,dt/(zgrb+1.));
14603 fBurstParameters->AddSignal(E,"EnergyOn");
14604 if (hAeffProfile)
14605 {
14606 thetamu=rmu.GetX(2,"sph","rad");
14607 gbin=hAeffProfile->FindFixBin(log10(E),cos(thetamu));
14608 if (gbin>0 && gbin<nbinsA+1)
14609 {
14610 Aeff=hAeffProfile->GetBinContent(gbin);
14611 if (Aeff>0)
14612 {
14613 Fluence=1./Aeff;
14614 fBurstOnAeff.Enter(Aeff,Fluence,E,dang);
14615 }
14616 }
14617 }
14618 }
14619 else // Off-source patch
14620 {
14621 if (dangmax>dangmaxoff) dangmaxoff=dangmax;
14622 fBurstOffReco.Enter(zgrb,sigmagrb,sigmareco,sigmatot);
14623 fBurstOffMatch.Enter(E,dt,dang,dt/(zgrb+1.));
14624 fBurstParameters->AddSignal(E,"EnergyOff");
14625 if (hAeffProfile)
14626 {
14627 thetamu=rmu.GetX(2,"sph","rad");
14628 gbin=hAeffProfile->FindFixBin(log10(E),cos(thetamu));
14629 if (gbin>0 && gbin<nbinsA+1)
14630 {
14631 Aeff=hAeffProfile->GetBinContent(gbin);
14632 if (Aeff>0)
14633 {
14634 Fluence=1./Aeff;
14635 fBurstOffAeff.Enter(Aeff,Fluence,E,dang);
14636 }
14637 }
14638 }
14639 }
14640 } // End of nbkg loop
14641 } // End of background nmu
14642 } // End of loop over the patches for recording background events
14643
14644 // Generate the GRB related signal event(s) in the search window.
14645 // The GRB position gets Gaussian smeared to reflect the actual position.
14646 // The time difference between the gammas and the neutrinos gets corrected
14647 // for the GRB redshift and smeared by the detector time resolution.
14648 // The muon direction gets modified to account for the kinematical opening angle
14649 // w.r.t. the neutrino direction and Gaussian smeared by the detector angular resolution.
14650
14651 // Prevent statistical overfluctuation in number of GRB signal events if requested by fGrbnu<0
14652 if ((fSigEmode=="SigE" && (fGrbnu>=0 || nmugrb<int(fabs(fGrbnu)*float(fNgrbs)))) || fSigEmode!="SigE")
14653 {
14654 // The real GRB position
14655
14656 if (fSigEmode=="SigE") // Signal strength set via user provided burst parameter "Grbnu"
14657 {
14658 // nsig is the average number of signal events for this burst
14659 nsig=fabs(fGrbnu);
14660
14661 // Apply Poisson fluctuations, if selected by the user
14662 if (fGrbnu>0) nsig=fRan->Poisson(nsig);
14663
14664 nmu=int(nsig);
14665 if (nsig>0 && !nmu && fRan->Uniform()<fabs(fGrbnu)) nmu=1;
14666
14667 // Use the full energy range as provided by the user
14668 elow=-1;
14669 eup=-1;
14670 nsig=1;
14671 GetSignal(dgrb,thetagrb,"deg",phigrb,"deg","loc",tx,igrb+1);
14672 }
14673 else // Signal strength set via user provided Fluence, Flux or Intensity
14674 {
14675 xaxis=0;
14676 yaxis=0;
14677 nbinsx=0;
14678 nbinsy=0;
14679 if (hSigNuCountProfile)
14680 {
14681 xaxis=hSigNuCountProfile->GetXaxis();
14682 yaxis=hSigNuCountProfile->GetYaxis();
14683 nbinsx=xaxis->GetNbins();
14684 nbinsy=yaxis->GetNbins();
14685 }
14686 nmu=nbinsx; // nmu will loop over all the energy bins for this GRB at the corresponding theta position
14687
14688 // Obtain the GRB position in local coordinates at the mean signal detection time
14689 if (!fInburst) // Neutrino and gamma production decoupled
14690 {
14691 dt=fDtnu;
14692 dt=dt*(zgrb+1.);
14693 }
14694 else // Coupled neutrino and gamma production
14695 {
14696 dt=fDtnu*t90grb;
14697 }
14698 tmu=*tx;
14699 tmu.AddSec(dt);
14700 GetSignal(dgrb,thetagrb,"deg",phigrb,"deg","loc",&tmu,igrb+1);
14701 }
14702
14703 rgrb.SetPosition(1,thetagrb,phigrb,"sph","deg");
14704
14705 // The real GRB position (rgrb2) in local coordinates
14706 rgrb2.Load(rgrb);
14707 SmearPosition(rgrb2,sigmagrb);
14708
14709 for (Int_t imu=0; imu<nmu; imu++)
14710 {
14711 // Check for possible signal in case a Fluence, Flux or Intensity was specified
14712 if (fSigEmode!="SigE" && hSigNuCountProfile)
14713 {
14714 ybin=yaxis->FindFixBin(cos(thetagrb*pi/180.));
14715 if (ybin<1 || ybin>nbinsy) continue;
14716
14717 // Investigate whether a signal will result at this energy
14718 nsig=hSigNuCountProfile->GetBinContent(imu+1,ybin);
14719
14720 if (nsig<=0) continue;
14721
14722 // Boundaries of this energy bin to provide a random energy below
14723 elow=xaxis->GetBinLowEdge(imu+1);
14724 eup=xaxis->GetBinUpEdge(imu+1);
14725 elow=pow(10,elow);
14726 eup=pow(10,eup);
14727
14728 // A steady flux is assumed during the complete obervation time
14729 if (fSigEmode!="SigS") nsig=nsig*fDtwin*fTfact;
14730
14731 // An isotropic diffuse flux is assumed when an Intensity was specified
14732 if (fSigEmode=="SigI") nsig=nsig*fOmegaDecl;
14733
14734 // Apply a distance weight, if requested by the user
14735 if (fDweight && fDweightSum>0)
14736 {
14737 dweight=sx->GetSignal("Dweight");
14738 nsig=nsig*float(fNgrbs)*dweight/fDweightSum;
14739 }
14740
14741 // Apply Poisson fluctuations, if selected by the user
14742 if (nsig>0 && fGrbnu>0) nsig=fRan->Poisson(nsig);
14743
14744 if (nsig>0 && nsig<1)
14745 {
14746 if (fRan->Uniform()<nsig) nsig=1;
14747 }
14748 }
14749
14750 // Process all signal events for this (energy,theta) location in the CountProfile
14751 // or just the next of "nmu" signal events as provided via the burst parameter "Grbnu"
14752 for (Int_t isig=0; isig<int(nsig); isig++)
14753 {
14754 if (!fInburst) // Neutrino and gamma production decoupled
14755 {
14756 if (fDtnus<0) // Sigma in units of T90
14757 {
14758 dt=fRan->Gauss(fDtnu,fabs(fDtnus)*t90grb);
14759 }
14760 else // Sigma in seconds
14761 {
14762 dt=fRan->Gauss(fDtnu,fDtnus);
14763 }
14764 dt=dt*(zgrb+1.);
14765 }
14766 else // Coupled neutrino and gamma production
14767 {
14768 if (fDtnus<0) // Sigma in units of T90
14769 {
14770 dt=fRan->Gauss(fDtnu*t90grb,fabs(fDtnus)*t90grb);
14771 }
14772 else // Sigma in seconds
14773 {
14774 dt=fRan->Gauss(fDtnu*t90grb,fDtnus);
14775 }
14776 }
14777 if (fTimres>0) dt=fRan->Gauss(dt,fTimres);
14778
14779 // Convert dt from seconds to the selected Tunit
14780 dt=dt/fTfact;
14781
14782 // The real direction of the GRB signal
14783 rmu.Load(rgrb2);
14784
14785 // Obtain a random energy from the GRB signal energy profile
14786 E=GetBurstSignalEnergy(elow,eup);
14787
14788 nmugrb++;
14789
14790 if (fSigEmode=="SigE")
14791 {
14792 // Injected energy at the source
14793 if (hSigE) hSigE->Fill(E);
14794
14795 // Reduce the energy due to the cosmological redshift effect
14796 if (fEzcor) E=E/(zgrb+1.);
14797 }
14798
14799 if (hSigEzcor) hSigEzcor->Fill(E);
14800
14801 if (E<0 || E<fEmin || E>fEmax) continue;
14802
14803 // Modification to account for the neutrino-lepton kinematic opening angle
14804 if (fKinangle>0)
14805 {
14806 Int_t mode=fKinangle-1;
14807 ang=GetNeutrinoAngle(E,"deg",mode);
14808 if (ang>0) ShiftPosition(rmu,ang);
14809 }
14810
14811 // Smearing according to the reconstruction angular resolution
14812 sigmareco=GetBurstRecoAngres(E,E);
14813 if (sigmareco<0) sigmareco=fAngresfix;
14814
14815 if (sigmareco<fAngresmin || sigmareco>fAngresmax) continue;
14816
14817 SmearPosition(rmu,sigmareco);
14818
14819 // Determine angular difference w.r.t. the presumed GRB position
14820 dang=rgrb.GetOpeningAngle(rmu,"deg");
14821
14822 sigmatot=-1;
14823 if (fSumsigmas==-1) sigmatot=sigmareco;
14824 if (fSumsigmas==0) sigmatot=sigmagrb;
14825 if (fSumsigmas==1) sigmatot=sigmagrb+sigmareco;
14826 if (fSumsigmas==2) sigmatot=sqrt(sigmagrb*sigmagrb+sigmareco*sigmareco);
14827
14828 // Determine the dynamic angular window including the track reco uncertainty
14829 if (!fixedwinset)
14830 {
14831 dangmax=-1;
14832 if (sigmatot>=0) dangmax=fabs(fDawin*sigmatot);
14833 }
14834
14835 if (fDatype>=0 && dang>dangmax) continue;
14836
14837 if (dt<fTmin || dt>fTmax) continue;
14838
14839 if (dangmax>dangmaxon) dangmaxon=dangmax;
14840
14841 fBurstOnReco.Enter(zgrb,sigmagrb,sigmareco,sigmatot);
14842 fBurstOnMatch.Enter(E,dt,dang,dt/(zgrb+1.));
14843 fBurstSigReco.Enter(zgrb,sigmagrb,sigmareco,sigmatot);
14844 fBurstSignal.Enter(E,dt,dang,dt/(zgrb+1.));
14845 fBurstParameters->AddSignal(E,"EnergyOn");
14846 fBurstParameters->AddSignal(E,"EnergySig");
14847 if (hAeffProfile)
14848 {
14849 thetamu=rmu.GetX(2,"sph","rad");
14850 gbin=hAeffProfile->FindFixBin(log10(E),cos(thetamu));
14851 if (gbin>0 && gbin<nbinsA+1)
14852 {
14853 Aeff=hAeffProfile->GetBinContent(gbin);
14854 if (Aeff>0)
14855 {
14856 Fluence=1./Aeff;
14857 fBurstOnAeff.Enter(Aeff,Fluence,E,dang);
14858 fBurstSigAeff.Enter(Aeff,Fluence,E,dang);
14859 }
14860 }
14861 }
14862 } // End of nsig loop
14863 } // End of signal nmu loop
14864 } // End of processing of the signal events of this burst
14865
14866 if (fixedwinset) continue;
14867
14868 // Store the dynamic On-source and Off-source maximum (solid) angles that are encountered for this burst
14869 if (fDawin<0) // Local zenith band centered at the GRB position at its trigger time
14870 {
14871 GetSignal(dgrb,thetagrb,"deg",phigrb,"deg","loc",tx,igrb+1);
14872 thlow=thetagrb-0.5*dangmaxon;
14873 thup=thetagrb+0.5*dangmaxon;
14874 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
14875 sx->SetSignal(dangmaxon,"dangmaxOn");
14876 sx->SetSignal(solidangle,"OmegaOn");
14877 thlow=thetagrb-0.5*dangmaxoff;
14878 thup=thetagrb+0.5*dangmaxoff;
14879 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
14880 sx->SetSignal(dangmaxoff,"dangmaxOff");
14881 sx->SetSignal(solidangle*float(fNbkg),"OmegaOff");
14882 }
14883 else // Circle around GRB position
14884 {
14885 thlow=0;
14886 thup=dangmaxon;
14887 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
14888 sx->SetSignal(solidangle,"OmegaOn");
14889 sx->SetSignal(dangmaxon,"dangmaxOn");
14890 thup=dangmaxoff;
14891 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
14892 sx->SetSignal(dangmaxoff,"dangmaxOff");
14893 sx->SetSignal(solidangle*float(fNbkg),"OmegaOff");
14894 }
14895 } // End of loop over the individual GRBs
14896
14897 // Remove the temporary storage of the background event
14898 if (fNgrbs>0) RemoveSignal(fNgrbs+1,0,0);
14899
14900 // Compensate statistical underfluctuation in number of GRB signal events if requested by fGrbnu<0
14901 if (fGrbnu<0 && fSigEmode=="SigE") BurstCompensate(nmugrb);
14902
14903 // Determine the On-source and Off-source total stacked solid angles that have been encountered
14904 name="SolidangleOn";
14905 fBurstParameters->AddNamedSlot(name);
14906 fBurstParameters->SetSignal(0,name);
14907 name="SolidangleOff";
14908 fBurstParameters->AddNamedSlot(name);
14909 fBurstParameters->SetSignal(0,name);
14910 for (Int_t igrb=1; igrb<=fNgrbs; igrb++)
14911 {
14912 sx=GetSignal(igrb);
14913
14914 if (!sx) continue;
14915
14916 solidangle=sx->GetSignal("OmegaOn");
14917 fBurstParameters->AddSignal(solidangle,"SolidangleOn");
14918 solidangle=sx->GetSignal("OmegaOff");
14919 fBurstParameters->AddSignal(solidangle,"SolidangleOff");
14920 }
14921
14922 // Store the number of recorded burst signal events
14923 fBurstParameters->AddNamedSlot("Nmugrb");
14924 fBurstParameters->SetSignal(nmugrb,"Nmugrb");
14925
14926 // Determine and list the burst statistics
14928}
14929
14931{
14943
14944 Double_t pi=acos(-1.);
14945
14946 // Retrieve the burst analysis data mode
14947 // mode : 0 --> Analysis based on simulated data via GenBurstSignals()
14948 // 1 --> Analysis based on real data via MatchBurstData()
14949 Int_t mode=TMath::Nint(fBurstParameters->GetSignal("BurstDataMode"));
14950
14951 // Retrieve the needed parameters
14952 Int_t fNgrbs=TMath::Nint(fBurstParameters->GetSignal("Ngrbs"));
14953 Int_t fNbkg=TMath::Nint(fBurstParameters->GetSignal("Nbkg"));
14954 Int_t fTunits=TMath::Nint(fBurstParameters->GetSignal("Tunits"));
14955 Float_t fTfact=fBurstParameters->GetSignal("Tfact");
14956 Float_t fTmin=fBurstParameters->GetSignal("Tmin");
14957 Float_t fTmax=fBurstParameters->GetSignal("Tmax");
14958 Int_t fTbint90=TMath::Nint(fBurstParameters->GetSignal("Tbint90"));
14959 Float_t fTbin=fBurstParameters->GetSignal("Tbin");
14960 Float_t fVarTbin=fBurstParameters->GetSignal("VarTbin");
14961 Float_t fAbin=fBurstParameters->GetSignal("Abin");
14962 Float_t fAvgrbz=fBurstParameters->GetSignal("Avgrbz");
14963 Float_t fAvgrbt90=fBurstParameters->GetSignal("Avgrbt90");
14964 Float_t fRbkgDecl=fBurstParameters->GetSignal("RbkgDecl");
14965 Float_t fSolidangleOn=fBurstParameters->GetSignal("SolidangleOn");
14966 Float_t fSolidangleOff=fBurstParameters->GetSignal("SolidangleOff");
14967 Int_t fBBtime=TMath::Nint(fBurstParameters->GetSignal("BBtime"));
14968 Int_t fBBangle=TMath::Nint(fBurstParameters->GetSignal("BBangle"));
14969 Float_t fBBfpr=fBurstParameters->GetSignal("BBfpr");
14970
14971 TString tu="days";
14972 if (fTunits==1) tu="hours";
14973 if (fTunits==2) tu="sec";
14974 if (fTunits==3) tu="ns";
14975 if (fTunits==4) tu="ps";
14976
14977 Int_t non=fBurstOnMatch.GetN();
14978 Int_t noff=fBurstOffMatch.GetN();
14979 Int_t nsig=fBurstSignal.GetN();
14980 Double_t TminOn=fTmin;
14981 Double_t TmaxOn=fTmax;
14982 Double_t TminOff=fTmin;
14983 Double_t TmaxOff=fTmax;
14984
14985 if (fTmax<=fTmin)
14986 {
14987 TminOn=fBurstOnMatch.GetMinimum("dtime");
14988 TmaxOn=fBurstOnMatch.GetMaximum("dtime");
14989 TminOff=fBurstOffMatch.GetMinimum("dtime");
14990 TmaxOff=fBurstOffMatch.GetMaximum("dtime");
14991 }
14992
14993 Double_t AminOn=fBurstOnMatch.GetMinimum("dang");
14994 Double_t AmaxOn=fBurstOnMatch.GetMaximum("dang");
14995 Double_t AminOff=fBurstOffMatch.GetMinimum("dang");
14996 Double_t AmaxOff=fBurstOffMatch.GetMaximum("dang");
14997
14998 // Update the time window sizes and the average number of background events in them
14999 Float_t DtwinOn=TmaxOn-TminOn;
15000 Float_t DtwinOff=TmaxOff-TminOff;
15001 Float_t NbkgWinOn=fRbkgDecl*DtwinOn*fTfact;
15002 Float_t NbkgWinOff=fRbkgDecl*DtwinOff*fTfact;
15003
15004 TString title;
15005 TString name;
15006 TString s;
15007 Float_t xmin=0;
15008 Float_t xmax=0;
15009 TAxis* axis=0;
15010 Int_t nbins=0;
15011 Double_t binsize=0;
15012 Double_t binsizecos=0;
15013 Int_t nabinsOn=0;
15014 Double_t abinsizeOn=0;
15015 Int_t nabinsOff=0;
15016 Double_t abinsizeOff=0;
15017
15018 // The source redshift, position and reconstruction uncertainty histograms
15019 TH1F* hOnSourceZ=0;
15020 TH1F* hOffSourceZ=0;
15021 TH1F* hOnSigSourceZ=0;
15022 TH1F* hOnSigmaSource=0;
15023 TH1F* hOffSigmaSource=0;
15024 TH1F* hOnSigSigmaSource=0;
15025 TH1F* hOnSigmaReco=0;
15026 TH1F* hOffSigmaReco=0;
15027 TH1F* hOnSigSigmaReco=0;
15028 TH1F* hOnSigmaComb=0;
15029 TH1F* hOffSigmaComb=0;
15030 TH1F* hOnSigSigmaComb=0;
15031 nbins=100;
15032 if (fBurstOnReco.GetN())
15033 {
15034 title.Form("On-Source object redshifts with matching event(s);Redshift;Counts");
15035 hOnSourceZ=new TH1F("hOnSourceZ",title,nbins,1,0);
15036 hOnSourceZ->SetBuffer(non);
15037
15038 title.Form("On-Source object position uncertainties with matching event(s);Object position angular uncertainty (sigma in degrees);Counts");
15039 hOnSigmaSource=new TH1F("hOnSigmaSource",title,nbins,1,0);
15040 hOnSigmaSource->SetBuffer(non);
15041
15042 title.Form("On-source event reconstruction uncertainties in the final sample;Event angular reconstruction uncertainty (sigma in degrees);Counts");
15043 hOnSigmaReco=new TH1F("hOnSigmaReco",title,nbins,1,0);
15044 hOnSigmaReco->SetBuffer(non);
15045
15046 title.Form("On-source combined object position and event reconstruction uncertainty;Combined object position and event reco angular uncertainty (sigma in degrees);Counts");
15047 hOnSigmaComb=new TH1F("hOnSigmaComb",title,nbins,1,0);
15048 hOnSigmaComb->SetBuffer(non);
15049 }
15050
15051 if (fBurstOffReco.GetN())
15052 {
15053 title.Form("Off-Source object redshifts with matching event(s);Redshift;Counts");
15054 hOffSourceZ=new TH1F("hOffSourceZ",title,nbins,1,0);
15055 hOffSourceZ->SetBuffer(noff);
15056
15057 title.Form("Off-Source object position uncertainties with matching event(s);Object position angular uncertainty (sigma in degrees);Counts");
15058 hOffSigmaSource=new TH1F("hOffSigmaSource",title,nbins,1,0);
15059 hOffSigmaSource->SetBuffer(noff);
15060
15061 title.Form("Off-source event reconstruction uncertainties in the final sample;Event angular reconstruction uncertainty (sigma in degrees);Counts");
15062 hOffSigmaReco=new TH1F("hOffSigmaReco",title,nbins,1,0);
15063 hOffSigmaReco->SetBuffer(noff);
15064
15065 title.Form("Off-source combined object position and event reconstruction uncertainty;Combined object position and event reco angular uncertainty (sigma in degrees);Counts");
15066 hOffSigmaComb=new TH1F("hOffSigmaComb",title,nbins,1,0);
15067 hOffSigmaComb->SetBuffer(noff);
15068 }
15069
15070 if (fBurstSigReco.GetN())
15071 {
15072 title.Form("On-Source object redshifts with matching simulated signal event(s);Redshift;Counts");
15073 hOnSigSourceZ=new TH1F("hOnSigSourceZ",title,nbins,1,0);
15074 hOnSigSourceZ->SetBuffer(nsig);
15075
15076 title.Form("On-Source object position uncertainties with matching simulated signal event(s);Object position angular uncertainty (sigma in degrees);Counts");
15077 hOnSigSigmaSource=new TH1F("hOnSigSigmaSource",title,nbins,1,0);
15078 hOnSigSigmaSource->SetBuffer(nsig);
15079
15080 title.Form("On-source simulated signal event reconstruction uncertainties in the final sample;Event angular reconstruction uncertainty (sigma in degrees);Counts");
15081 hOnSigSigmaReco=new TH1F("hOnSigSigmaReco",title,nbins,1,0);
15082 hOnSigSigmaReco->SetBuffer(nsig);
15083
15084 title.Form("On-source combined object position and simulated signal event reconstruction uncertainty;Combined object position and event reco angular uncertainty (sigma in degrees);Counts");
15085 hOnSigSigmaComb=new TH1F("hOnSigSigmaComb",title,nbins,1,0);
15086 hOnSigSigmaComb->SetBuffer(nsig);
15087 }
15088
15089 // The energy histograms
15090 TH1F* hOnE=0;
15091 TH1F* hOffE=0;
15092 TH1F* hOnSigE=0;
15093 nbins=1000;
15094 if (non)
15095 {
15096 title.Form("On-source reconstructed event energy in the final sample;Event energy in GeV;Counts");
15097 if (!mode) title.ReplaceAll("reconstructed","simulated");
15098 hOnE=new TH1F("hOnE",title,nbins,1,0);
15099 }
15100 if (noff)
15101 {
15102 title.Form("Off-source reconstructed event energy in the final sample;Event energy in GeV;Counts");
15103 if (!mode) title.ReplaceAll("reconstructed","simulated");
15104 hOffE=new TH1F("hOffE",title,nbins,1,0);
15105 }
15106 if (nsig)
15107 {
15108 title.Form("On-source simulated signal event energy in the final sample;Event energy in GeV;Counts");
15109 hOnSigE=new TH1F("hOnSigE",title,nbins,1,0);
15110 }
15111
15112 // Additional text for histo titles to indicate scrambling of the corresponding data
15113 TString scrt=""; // Time scrambling
15114 TString scrp=""; // Position scrambling
15115 if (fTscmode>0) scrt="(scrambled)";
15116 if (fRscmode>0 || fTscmode==3) scrp="(scrambled)";
15117
15118 // Create the angular separation histograms
15119 TH1F* hOna=0;
15120 TH1F* hOffa=0;
15121 TH1F* hOnSiga=0;
15122 TH1F* hOnCosa=0;
15123 TH1F* hOffCosa=0;
15124 TH1F* hOnSigcosa=0;
15125 if (non && fAbin)
15126 {
15127 if (fAbin>0)
15128 {
15129 binsize=fAbin;
15130 nbins=int((AmaxOn-AminOn)/binsize);
15131 }
15132 else
15133 {
15134 nbins=int(((AmaxOn-AminOn)/180.)*NbkgWinOn*float(fNgrbs)/fabs(fAbin));
15135 if (nbins) binsize=(AmaxOn-AminOn)/float(nbins);
15136 }
15137 if (nbins)
15138 {
15139 title.Form("Reconstructed %-s opening angle of on-source events in time window;Opening angle (degrees);Counts per %-.3g degrees",scrp.Data(),binsize);
15140 hOna=new TH1F("hOna",title,nbins+1,AminOn,AmaxOn+binsize);
15141 }
15142 else
15143 {
15144 nbins=100;
15145 binsize=AmaxOn/float(nbins);
15146 title.Form("Reconstructed %-s opening angle of on-source events in time window;Opening angle (degrees);Counts per %-.3g degrees",scrp.Data(),binsize);
15147 hOna=new TH1F("hOna",title,nbins+2,AminOn-binsize,AmaxOn+binsize);
15148 }
15149 nabinsOn=nbins;
15150 abinsizeOn=binsize;
15151 if (nbins) binsizecos=(cos(AminOn*pi/180.)-cos(AmaxOn*pi/180.))/float(nbins);
15152 if (binsizecos>0)
15153 {
15154 title.Form("Reconstructed %-s cos(opening angle) of on-source events in time window;cos(opening angle);Counts per %-.3g",scrp.Data(),binsizecos);
15155 hOnCosa=new TH1F("hOnCosa",title,nbins+1,cos(AmaxOn*pi/180.),cos(AminOn*pi/180.)+binsizecos);
15156 }
15157 else
15158 {
15159 nbins=100;
15160 binsizecos=fabs(cos(AmaxOn*pi/180.))/float(nbins);
15161 title.Form("Reconstructed %-s cos(opening angle) of on-source events in time window;cos(opening angle);Counts per %-.3g",scrp.Data(),binsizecos);
15162 hOnCosa=new TH1F("hOnCosa",title,nbins+2,cos(AmaxOn*pi/180.)-binsizecos,cos(AminOn*pi/180.)+binsizecos);
15163 }
15164 }
15165 if (nsig && nbins)
15166 {
15167 title.Form("Reconstructed opening angle of on-source simulated signal events in time window;Opening angle (degrees);Counts per %-.3g degrees",binsize);
15168 hOnSiga=new TH1F("hOnSiga",title,nbins+2,AminOn-binsize,AmaxOn+binsize);
15169 title.Form("Reconstructed cos(opening angle) of on-source simulated signal events in time window;cos(opening angle);Counts per %-.3g",binsizecos);
15170 hOnSigcosa=new TH1F("hOnSigcosa",title,nbins+2,cos(AmaxOn*pi/180.)-binsizecos,cos(AminOn*pi/180.)+binsizecos);
15171 }
15172 nbins=0;
15173 binsize=0;
15174 binsizecos=0;
15175 if (noff && fAbin)
15176 {
15177 if (fAbin>0)
15178 {
15179 binsize=fAbin;
15180 nbins=int((AmaxOff-AminOff)/binsize);
15181 }
15182 else
15183 {
15184 nbins=int(((AmaxOff-AminOff)/180.)*NbkgWinOff*float(fNgrbs)*float(fNbkg)/fabs(fAbin));
15185 if (nbins) binsize=(AmaxOff-AminOff)/float(nbins);
15186 }
15187 if (nbins)
15188 {
15189 title.Form("Reconstructed opening angle of off-source events in time window;Opening angle (degrees);Counts per %-.3g degrees",binsize);
15190 hOffa=new TH1F("hOffa",title,nbins+1,AminOff,AmaxOff+binsize);
15191 }
15192 else
15193 {
15194 nbins=100;
15195 binsize=AmaxOff/float(nbins);
15196 title.Form("Reconstructed opening angle of off-source events in time window;Opening angle (degrees);Counts per %-.3g degrees",binsize);
15197 hOffa=new TH1F("hOffa",title,nbins+2,AminOff-binsize,AmaxOff+binsize);
15198 }
15199 nabinsOff=nbins;
15200 abinsizeOff=binsize;
15201 if (nbins) binsizecos=(cos(AminOff*pi/180.)-cos(AmaxOff*pi/180.))/float(nbins);
15202 if (binsizecos>0)
15203 {
15204 title.Form("Reconstructed cos(opening angle) of off-source events in time window;cos(opening angle);Counts per %-.3g",binsizecos);
15205 hOffCosa=new TH1F("hOffCosa",title,nbins+1,cos(AmaxOff*pi/180.),cos(AminOff*pi/180.)+binsizecos);
15206 }
15207 else
15208 {
15209 nbins=100;
15210 binsizecos=fabs(cos(AmaxOff*pi/180.))/float(nbins);
15211 title.Form("Reconstructed cos(opening angle) of off-source events in time window;cos(opening angle);Counts per %-.3g",binsizecos);
15212 hOffCosa=new TH1F("hOffCosa",title,nbins+2,cos(AmaxOff*pi/180.)-binsizecos,cos(AminOff*pi/180.)+binsizecos);
15213 }
15214 }
15215
15216 // Create the arrival time histograms
15217 TH1F* hOnt=0;
15218 TH1F* hOfft=0;
15219 TH1F* hOnSigt=0;
15220 TH2F* hOnta=0;
15221 TH2F* hOffta=0;
15222 TH2F* hOnSigta=0;
15223 TH2F* hOnZta=0;
15224 TH2F* hOffZta=0;
15225 TH2F* hOnSigZta=0;
15226
15227 // The redshift corrected arrival time histograms
15228 TH1F* hOnZt=0;
15229 TH1F* hOffZt=0;
15230 TH1F* hOnSigZt=0;
15231
15232 nbins=0;
15233 binsize=0;
15234 TString addtitle;
15235 addtitle.Form(" (=%-g*<T90>)",fTbin);
15236 if (fTbin<0) addtitle.Form(" (~%-g counts/bin)",fabs(fTbin));
15237 if (fabs(fTbin)>0) // Fixed time bins
15238 {
15239 // Automatic time binning to get the specified maximal bkg counts per bin
15240 nbins=int(NbkgWinOn*float(fNgrbs)/fabs(fTbin));
15241 Int_t temp=int(NbkgWinOff*float(fNgrbs)*float(fNbkg)/fabs(fTbin));
15242 if (temp>nbins) nbins=temp;
15243 if (nbins) binsize=DtwinOn/float(nbins);
15244
15245 if (fTbin>0) // User defined time bin size
15246 {
15247 binsize=fTbin;
15248 if (fTbint90) binsize=fTbin*fabs(fAvgrbt90)/fTfact;
15249 nbins=DtwinOn/binsize;
15250 }
15251 if (nbins && non)
15252 {
15253 title.Form("Arrival times %-s of on-source events in time window;Event arrival time (in %-s) w.r.t. burst trigger;Counts per %-.3g %-s",scrt.Data(),tu.Data(),binsize,tu.Data());
15254 if (fTbint90 || fTbin<0) title+=addtitle;
15255 hOnt=new TH1F("hOnt",title,nbins+2,TminOn-binsize,TmaxOn+binsize);
15256 title.Form("Arrival time %-s vs. reconstructed %-s opening angle of on-source events in time window;Opening angle (degrees);Event arrival time (in %-s) w.r.t. burst trigger",scrt.Data(),scrp.Data(),tu.Data());
15257 hOnta=new TH2F("hOnta",title,nabinsOn+2,AminOn-abinsizeOn,AmaxOn+abinsizeOn,nbins+2,TminOn-binsize,TmaxOn+binsize);
15258 title.Form("Redshift corrected arrival times %-s of on-source events in time window;Event arrival time (in %-s) w.r.t. burst trigger;Counts per %-.3g %-s",scrt.Data(),tu.Data(),binsize,tu.Data());
15259 if (fTbint90 || fTbin<0) title+=addtitle;
15260 hOnZt=new TH1F("hOnZt",title,nbins+2,TminOn-binsize,TmaxOn+binsize);
15261 title.Form("Redshift corrected %-s arrival time vs. reconstructed %-s opening angle of on-source events in time window;Opening angle (degrees);Event arrival time (in %-s) w.r.t. burst trigger",scrt.Data(),scrp.Data(),tu.Data());
15262 hOnZta=new TH2F("hOnZta",title,nabinsOn+2,AminOn-abinsizeOn,AmaxOn+abinsizeOn,nbins+2,TminOn-binsize,TmaxOn+binsize);
15263 }
15264 if (nbins && nsig)
15265 {
15266 title.Form("Arrival times of on-source simulated signal events in time window;Event arrival time (in %-s) w.r.t. burst trigger;Counts per %-.3g %-s",tu.Data(),binsize,tu.Data());
15267 if (fTbint90 || fTbin<0) title+=addtitle;
15268 hOnSigt=new TH1F("hOnSigt",title,nbins+2,TminOn-binsize,TmaxOn+binsize);
15269 title.Form("Arrival time vs. reconstructed opening angle of on-source simulated signal events in time window;Opening angle (degrees);Event arrival time (in %-s) w.r.t. burst trigger",tu.Data());
15270 hOnSigta=new TH2F("hOnSigta",title,nabinsOn+2,AminOn-abinsizeOn,AmaxOn+abinsizeOn,nbins+2,TminOn-binsize,TmaxOn+binsize);
15271 title.Form("Redshift corrected arrival times of on-source simulated signal events in time window;Event arrival time (in %-s) w.r.t. burst trigger;Counts per %-.3g %-s",tu.Data(),binsize,tu.Data());
15272 if (fTbint90 || fTbin<0) title+=addtitle;
15273 hOnSigZt=new TH1F("hOnSigZt",title,nbins+2,TminOn-binsize,TmaxOn+binsize);
15274 title.Form("Redshift corrected arrival time vs. reconstructed opening angle of on-source simulated signal events in time window;Opening angle (degrees);Event arrival time (in %-s) w.r.t. burst trigger",tu.Data());
15275 hOnSigZta=new TH2F("hOnSigZta",title,nabinsOn+2,AminOn-abinsizeOn,AmaxOn+abinsizeOn,nbins+2,TminOn-binsize,TmaxOn+binsize);
15276 }
15277
15278 if (fTbin>0) // User defined time bin size
15279 {
15280 binsize=fTbin;
15281 if (fTbint90) binsize=fTbin*fabs(fAvgrbt90)/fTfact;
15282 nbins=DtwinOff/binsize;
15283 }
15284 if (nbins && noff)
15285 {
15286 title.Form("Arrival times of off-source events in time window;Event arrival time (in %-s) w.r.t. burst trigger;Counts per %-.3g %-s",tu.Data(),binsize,tu.Data());
15287 if (fTbint90 || fTbin<0) title+=addtitle;
15288 hOfft=new TH1F("hOfft",title,nbins+2,TminOff-binsize,TmaxOff+binsize);
15289 title.Form("Arrival time vs. reconstructed opening angle of off-source events in time window;Opening angle (degrees);Event arrival time (in %-s) w.r.t. burst trigger",tu.Data());
15290 hOffta=new TH2F("hOffta",title,nabinsOff+2,AminOff-abinsizeOff,AmaxOff+abinsizeOff,nbins+2,TminOff-binsize,TmaxOff+binsize);
15291 title.Form("Redshift corrected arrival times of off-source events in time window;Event arrival time (in %-s) w.r.t. burst trigger;Counts per %-.3g %-s",tu.Data(),binsize,tu.Data());
15292 if (fTbint90 || fTbin<0) title+=addtitle;
15293 hOffZt=new TH1F("hOffZt",title,nbins+2,TminOff-binsize,TmaxOff+binsize);
15294 title.Form("Redshift corrected arrival time vs. reconstructed opening angle of off-source events in time window;Opening angle (degrees);Event arrival time (in %-s) w.r.t. burst trigger",tu.Data());
15295 hOffZta=new TH2F("hOffZta",title,nabinsOff+2,AminOff-abinsizeOff,AmaxOff+abinsizeOff,nbins+2,TminOff-binsize,TmaxOff+binsize);
15296 }
15297 }
15298 else // Variable time bins
15299 {
15300 Double_t* binarr=0;
15301 Int_t nbx=int(DtwinOn/fVarTbin);
15302 Float_t gamma=fabs(fAvgrbz)+1.;
15303 Float_t* bins=new Float_t[nbx];
15304 nbins=0;
15305 Float_t xlow=0,xup=0,size=fVarTbin;
15306 for (Int_t i=0; i<nbx-1; i++)
15307 {
15308 xup=xlow+size;
15309 if (xup>DtwinOn/2.) // Store the last lowerbound
15310 {
15311 bins[i]=xlow;
15312 nbins++;
15313 break;
15314 }
15315 bins[i]=xlow;
15316 nbins++;
15317 xlow=xup;
15318 size=xlow*gamma;
15319 }
15320 binarr=new Double_t[2*nbins-1];
15321 for (Int_t j=nbins; j>0; j--)
15322 {
15323 binarr[nbins-j]=-bins[j-1];
15324 binarr[nbins+j-2]=bins[j-1];
15325 }
15326 nbins=2*nbins-2;
15327 if (nbins && non)
15328 {
15329 title.Form("Arrival times %-s of on-source events in time window;Event arrival time (in %-s) w.r.t. burst trigger;Counts per time bin",scrt.Data(),tu.Data());
15330 hOnt=new TH1F("hOnt",title,nbins,binarr);
15331 if (nabinsOn)
15332 {
15333 title.Form("Arrival time %-s vs. reconstructed %-s opening angle of on-source events in time window;Opening angle (degrees);Event arrival time (in %-s) w.r.t. burst trigger",scrt.Data(),scrp.Data(),tu.Data());
15334 hOnta=new TH2F("hOnta",title,nabinsOn,AminOn,AmaxOn,nbins,binarr);
15335 }
15336 }
15337 if (nbins && noff)
15338 {
15339 title.Form("Arrival times of off-source events in time window;Event arrival time (in %-s) w.r.t. burst trigger;Counts per time bin",tu.Data());
15340 hOfft=new TH1F("hOfft",title,nbins,binarr);
15341 if (nabinsOff)
15342 {
15343 title.Form("Arrival time vs. reconstructed opening angle of off-source events in time window;Opening angle (degrees);Event arrival time (in %-s) w.r.t. burst trigger",tu.Data());
15344 hOffta=new TH2F("hOffta",title,nabinsOff,AminOff,AmaxOff,nbins,binarr);
15345 }
15346 }
15347 if (nbins && nsig)
15348 {
15349 title.Form("Arrival times of on-source simulated signal events in time window;Event arrival time (in %-s) w.r.t. burst trigger;Counts per time bin",tu.Data());
15350 hOnSigt=new TH1F("hOnSigt",title,nbins,binarr);
15351 if (nabinsOn)
15352 {
15353 title.Form("Arrival time vs. reconstructed opening angle of on-source simulated signal events in time window;Opening angle (degrees);Event arrival time (in %-s) w.r.t. burst trigger",tu.Data());
15354 hOnSigta=new TH2F("hOnSigta",title,nabinsOn,AminOn,AmaxOn,nbins,binarr);
15355 }
15356 }
15357
15358 delete[] binarr;
15359 }
15360
15361 // Fill the histograms
15362 Double_t value1=0;
15363 Double_t value2=0;
15364 Double_t value3=0;
15365 Double_t value4=0;
15366
15367 // The on-source data
15368 for (Int_t i=1; i<=fBurstOnReco.GetN(); i++)
15369 {
15370 value1=fBurstOnReco.GetEntry(i,"zburst");
15371 value2=fBurstOnReco.GetEntry(i,"sigmaburst");
15372 value3=fBurstOnReco.GetEntry(i,"sigmareco");
15373 value4=fBurstOnReco.GetEntry(i,"sigmacomb");
15374 if (hOnSourceZ) hOnSourceZ->Fill(value1);
15375 if (hOnSigmaSource) hOnSigmaSource->Fill(value2);
15376 if (hOnSigmaReco) hOnSigmaReco->Fill(value3);
15377 if (hOnSigmaComb) hOnSigmaComb->Fill(value4);
15378 }
15379
15380 for (Int_t i=1; i<=fBurstOnMatch.GetN(); i++)
15381 {
15382 value1=fBurstOnMatch.GetEntry(i,"E");
15383 value2=fBurstOnMatch.GetEntry(i,"dang");
15384 value3=fBurstOnMatch.GetEntry(i,"dtime");
15385 value4=fBurstOnMatch.GetEntry(i,"dtimez");
15386 if (hOnE) hOnE->Fill(value1);
15387 if (hOna) hOna->Fill(value2);
15388 if (hOnCosa) hOnCosa->Fill(cos(value2*pi/180.));
15389 if (hOnt) hOnt->Fill(value3);
15390 if (hOnta) hOnta->Fill(value2,value3);
15391 if (hOnZt) hOnZt->Fill(value4);
15392 if (hOnZta) hOnZta->Fill(value2,value4);
15393 }
15394
15395 // The off-source data
15396 for (Int_t i=1; i<=fBurstOffReco.GetN(); i++)
15397 {
15398 value1=fBurstOffReco.GetEntry(i,"zburst");
15399 value2=fBurstOffReco.GetEntry(i,"sigmaburst");
15400 value3=fBurstOffReco.GetEntry(i,"sigmareco");
15401 value4=fBurstOffReco.GetEntry(i,"sigmacomb");
15402 if (hOffSourceZ) hOffSourceZ->Fill(value1);
15403 if (hOffSigmaSource) hOffSigmaSource->Fill(value2);
15404 if (hOffSigmaReco) hOffSigmaReco->Fill(value3);
15405 if (hOffSigmaComb) hOffSigmaComb->Fill(value4);
15406 }
15407
15408 for (Int_t i=1; i<=fBurstOffMatch.GetN(); i++)
15409 {
15410 value1=fBurstOffMatch.GetEntry(i,"E");
15411 value2=fBurstOffMatch.GetEntry(i,"dang");
15412 value3=fBurstOffMatch.GetEntry(i,"dtime");
15413 value4=fBurstOffMatch.GetEntry(i,"dtimez");
15414 if (hOffE) hOffE->Fill(value1);
15415 if (hOffa) hOffa->Fill(value2);
15416 if (hOffCosa) hOffCosa->Fill(cos(value2*pi/180.));
15417 if (hOfft) hOfft->Fill(value3);
15418 if (hOffta) hOffta->Fill(value2,value3);
15419 if (hOffZt) hOffZt->Fill(value4);
15420 if (hOffZta) hOffZta->Fill(value2,value4);
15421 }
15422
15423 // The simulated signal data
15424 for (Int_t i=1; i<=fBurstSigReco.GetN(); i++)
15425 {
15426 value1=fBurstSigReco.GetEntry(i,"zburst");
15427 value2=fBurstSigReco.GetEntry(i,"sigmaburst");
15428 value3=fBurstSigReco.GetEntry(i,"sigmareco");
15429 value4=fBurstSigReco.GetEntry(i,"sigmacomb");
15430 if (hOnSigSourceZ) hOnSigSourceZ->Fill(value1);
15431 if (hOnSigSigmaSource) hOnSigSigmaSource->Fill(value2);
15432 if (hOnSigSigmaReco) hOnSigSigmaReco->Fill(value3);
15433 if (hOnSigSigmaComb) hOnSigSigmaComb->Fill(value4);
15434 }
15435
15436 for (Int_t i=1; i<=fBurstSignal.GetN(); i++)
15437 {
15438 value1=fBurstSignal.GetEntry(i,"E");
15439 value2=fBurstSignal.GetEntry(i,"dang");
15440 value3=fBurstSignal.GetEntry(i,"dtime");
15441 value4=fBurstSignal.GetEntry(i,"dtimez");
15442 if (hOnSigE) hOnSigE->Fill(value1);
15443 if (hOnSiga) hOnSiga->Fill(value2);
15444 if (hOnSigcosa) hOnSigcosa->Fill(cos(value2*pi/180.));
15445 if (hOnSigt) hOnSigt->Fill(value3);
15446 if (hOnSigta) hOnSigta->Fill(value2,value3);
15447 if (hOnSigZt) hOnSigZt->Fill(value4);
15448 if (hOnSigZta) hOnSigZta->Fill(value2,value4);
15449 }
15450
15452 // Bayesian block analysis of the arrival times //
15454 NcBlocks BB;
15455 TH1F hOnBBt;
15456 TH1F* hOnBBtN=0;
15457 TH1F hOnBBzt;
15458 TH1F* hOnBBztN=0;
15459 if (fBBtime && fBurstOnMatch.GetN())
15460 {
15461 BB.GetBlocks(fBurstOnMatch,"dtime",fBBfpr,&hOnBBt);
15462 title.Form("Bayesian blocks (fpr=%-g) for on-source arrival times %-s;Event arrival time (in %-s) w.r.t. burst trigger;Event rate (%-s^{-1}) for %-i stacked time windows",fBBfpr,scrt.Data(),tu.Data(),tu.Data(),fNgrbs);
15463 title.ReplaceAll("days^","day^");
15464 title.ReplaceAll("hours^","hour^");
15465 hOnBBt.SetNameTitle("hOnBBt",title);
15466
15467 // The per patch scaled corresponding histogram
15468 hOnBBtN=(TH1F*)hOnBBt.Clone("hOnBBtN");
15469 if (fNgrbs>1) hOnBBtN->Scale(1./float(fNgrbs));
15470 title.Form("Event rate (%-s^{-1}) scaled per time window",tu.Data());
15471 title.ReplaceAll("days^","day^");
15472 title.ReplaceAll("hours^","hour^");
15473 hOnBBtN->SetYTitle(title);
15474
15475 BB.GetBlocks(fBurstOnMatch,"dtimez",fBBfpr,&hOnBBzt);
15476 title.Form("Bayesian blocks (fpr=%-g) for redshift corrected on-source arrival times %-s;Event arrival time (in %-s) w.r.t. burst trigger;Event rate (%-s^{-1}) for %-i stacked time windows",fBBfpr,scrt.Data(),tu.Data(),tu.Data(),fNgrbs);
15477 title.ReplaceAll("days^","day^");
15478 title.ReplaceAll("hours^","hour^");
15479 hOnBBzt.SetNameTitle("hOnBBzt",title);
15480
15481 // The per patch scaled corresponding histogram
15482 hOnBBztN=(TH1F*)hOnBBzt.Clone("hOnBBztN");
15483 if (fNgrbs>1) hOnBBztN->Scale(1./float(fNgrbs));
15484 title.Form("Event rate (%-s^{-1}) scaled per time window",tu.Data());
15485 title.ReplaceAll("days^","day^");
15486 title.ReplaceAll("hours^","hour^");
15487 hOnBBztN->SetYTitle(title);
15488 }
15489 TH1F hOffBBt;
15490 TH1F* hOffBBtN=0;
15491 TH1F hOffBBzt;
15492 TH1F* hOffBBztN=0;
15493 if (fBBtime && fBurstOffMatch.GetN())
15494 {
15495 BB.GetBlocks(fBurstOffMatch,"dtime",fBBfpr,&hOffBBt);
15496 title.Form("Bayesian blocks for (fpr=%-g) off-source arrival times;Event arrival time (in %-s) w.r.t. burst trigger;Event rate (%-s^{-1}) for %-i stacked time windows",fBBfpr,tu.Data(),tu.Data(),fNgrbs*fNbkg);
15497 title.ReplaceAll("days^","day^");
15498 title.ReplaceAll("hours^","hour^");
15499 hOffBBt.SetNameTitle("hOffBBt",title);
15500
15501 // The per patch scaled corresponding histogram
15502 hOffBBtN=(TH1F*)hOffBBt.Clone("hOffBBtN");
15503 if (fNgrbs*fNbkg>1) hOffBBtN->Scale(1./float(fNgrbs*fNbkg));
15504 title.Form("Event rate (%-s^{-1}) scaled per time window",tu.Data());
15505 title.ReplaceAll("days^","day^");
15506 title.ReplaceAll("hours^","hour^");
15507 hOffBBtN->SetYTitle(title);
15508
15509 BB.GetBlocks(fBurstOffMatch,"dtimez",fBBfpr,&hOffBBzt);
15510 title.Form("Bayesian blocks (fpr=%-g) for redshift corrected off-source arrival times;Event arrival time (in %-s) w.r.t. burst trigger;Event rate (%-s^{-1}) for %-i stacked time windows",fBBfpr,tu.Data(),tu.Data(),fNgrbs*fNbkg);
15511 title.ReplaceAll("days^","day^");
15512 title.ReplaceAll("hours^","hour^");
15513 hOffBBzt.SetNameTitle("hOffBBzt",title);
15514
15515 // The per patch scaled corresponding histogram
15516 hOffBBztN=(TH1F*)hOffBBzt.Clone("hOffBBztN");
15517 if (fNgrbs*fNbkg>1) hOffBBztN->Scale(1./float(fNgrbs*fNbkg));
15518 title.Form("Event rate (%-s^{-1}) scaled per time window",tu.Data());
15519 title.ReplaceAll("days^","day^");
15520 title.ReplaceAll("hours^","hour^");
15521 hOffBBztN->SetYTitle(title);
15522 }
15523
15524 // Ratio On/Off for the arrival time Bayesian Block histograms
15525 TH1F hOnUBBtN;
15526 TH1F hOffUBBtN;
15527 TH1F hRatUBBtN;
15528 title.Form("Event rate (%-s^{-1}) scaled per time window",tu.Data());
15529 title.ReplaceAll("days^","day^");
15530 title.ReplaceAll("hours^","hour^");
15531 Float_t temp=0;
15532 Int_t nb1=0;
15533 Int_t nb2=0;
15534
15535 if (hOnBBtN && hOffBBtN)
15536 {
15537 axis=hOnBBtN->GetXaxis();
15538 xmin=axis->GetXmin();
15539 xmax=axis->GetXmax();
15540 axis=hOffBBtN->GetXaxis();
15541 temp=axis->GetXmin();
15542 if (temp<xmin) xmin=temp;
15543 temp=axis->GetXmax();
15544 if (temp>xmax) xmax=temp;
15545
15546 nb1=BB.Rebin(hOnBBtN,&hOnUBBtN,kFALSE,0,xmin,xmax);
15547 nb2=BB.Rebin(hOffBBtN,&hOffUBBtN,kFALSE,0,xmin,xmax);
15548 if (nb2>nb1) BB.Rebin(hOnBBtN,&hOnUBBtN,kFALSE,nb2,xmin,xmax);
15549 hOnUBBtN.SetName("hOnUBBtN");
15550 hOffUBBtN.SetName("hOffUBBtN");
15551 hOnUBBtN.SetYTitle(title);
15552 hOffUBBtN.SetYTitle(title);
15553 BB.Divide(&hOnUBBtN,&hOffUBBtN,&hRatUBBtN,kFALSE,1);
15554 hRatUBBtN.SetName("hRatUBBtN");
15555 hRatUBBtN.SetYTitle("Ratio");
15556 }
15557
15558
15559 TH1F hOnUBBztN;
15560 TH1F hOffUBBztN;
15561 TH1F hRatUBBztN;
15562 if (hOnBBztN && hOffBBztN)
15563 {
15564 axis=hOnBBztN->GetXaxis();
15565 xmin=axis->GetXmin();
15566 xmax=axis->GetXmax();
15567 axis=hOffBBztN->GetXaxis();
15568 temp=axis->GetXmin();
15569 if (temp<xmin) xmin=temp;
15570 temp=axis->GetXmax();
15571 if (temp>xmax) xmax=temp;
15572
15573 nb1=BB.Rebin(hOnBBztN,&hOnUBBztN,kFALSE,0,xmin,xmax);
15574 nb2=BB.Rebin(hOffBBztN,&hOffUBBztN,kFALSE,0,xmin,xmax);
15575 if (nb2>nb1) BB.Rebin(hOnBBztN,&hOnUBBztN,kFALSE,nb2,xmin,xmax);
15576 hOnUBBztN.SetName("hOnUBBztN");
15577 hOffUBBztN.SetName("hOffUBBztN");
15578 hOnUBBztN.SetYTitle(title);
15579 hOffUBBztN.SetYTitle(title);
15580 BB.Divide(&hOnUBBztN,&hOffUBBztN,&hRatUBBztN,kFALSE,1);
15581 hRatUBBztN.SetName("hRatUBBztN");
15582 hRatUBBztN.SetYTitle("Ratio");
15583 }
15584
15586 // Bayesian block analysis of the opening angles //
15588 TH1F hOnBBa;
15589 TH1F* hOnBBaN=0;
15590 Int_t nen=fBurstOnMatch.GetN();
15591 Double_t value=0;
15592 TArrayD tarr;
15593 Double_t* arr;
15594 if (fBBangle && nen)
15595 {
15596 tarr.Set(nen);
15597 for (Int_t i=1; i<=nen; i++)
15598 {
15599 value=fBurstOnMatch.GetEntry(i,"dang");
15600 tarr[i-1]=cos(value*pi/180.);
15601 }
15602 arr=tarr.GetArray();
15603 BB.GetBlocks(nen,arr,fBBfpr,&hOnBBa);
15604 title.Form("Bayesian blocks (fpr=%-g) for on-source angular differences;cos(opening angle) w.r.t. source location;Occurence density for %-i stacked patches",fBBfpr,fNgrbs);
15605 hOnBBa.SetNameTitle("hOnBBa",title);
15606
15607 // The per patch scaled corresponding histogram
15608 hOnBBaN=(TH1F*)hOnBBa.Clone("hOnBBaN");
15609 if (fNgrbs>1) hOnBBaN->Scale(1./float(fNgrbs));
15610 hOnBBaN->SetYTitle("Occurrence density scaled per patch");
15611 }
15612 TH1F hOffBBa;
15613 TH1F* hOffBBaN=0;
15614 nen=fBurstOffMatch.GetN();
15615 if (fBBangle && nen)
15616 {
15617 tarr.Set(nen);
15618 for (Int_t i=1; i<=nen; i++)
15619 {
15620 value=fBurstOffMatch.GetEntry(i,"dang");
15621 tarr[i-1]=cos(value*pi/180.);
15622 }
15623 arr=tarr.GetArray();
15624 BB.GetBlocks(nen,arr,fBBfpr,&hOffBBa);
15625 title.Form("Bayesian blocks (fpr=%-g) for off-source angular differences;cos(opening angle) w.r.t. source location;Occurence density for %-i stacked patches",fBBfpr,fNgrbs*fNbkg);
15626 hOffBBa.SetNameTitle("hOffBBa",title);
15627
15628 // The per patch scaled corresponding histogram
15629 hOffBBaN=(TH1F*)hOffBBa.Clone("hOffBBaN");
15630 if (fNgrbs*fNbkg>1) hOffBBaN->Scale(1./float(fNgrbs*fNbkg));
15631 hOffBBaN->SetYTitle("Occurrence density scaled per patch");
15632 }
15633
15634 // Ratio On/Off for the angular differences Bayesian Block histograms
15635 TH1F hOnUBBaN;
15636 TH1F hOffUBBaN;
15637 TH1F hRatUBBaN;
15638 title.Form("Occurrence density scaled per patch");
15639 temp=0;
15640 nb1=0;
15641 nb2=0;
15642
15643 if (hOnBBaN && hOffBBaN)
15644 {
15645 axis=hOnBBaN->GetXaxis();
15646 xmin=axis->GetXmin();
15647 xmax=axis->GetXmax();
15648 axis=hOffBBaN->GetXaxis();
15649 temp=axis->GetXmin();
15650 if (temp<xmin) xmin=temp;
15651 temp=axis->GetXmax();
15652 if (temp>xmax) xmax=temp;
15653
15654 nb1=BB.Rebin(hOnBBaN,&hOnUBBaN,kFALSE,0,xmin,xmax);
15655 nb2=BB.Rebin(hOffBBaN,&hOffUBBaN,kFALSE,0,xmin,xmax);
15656 if (nb2>nb1) BB.Rebin(hOnBBaN,&hOnUBBaN,kFALSE,nb2,xmin,xmax);
15657 hOnUBBaN.SetName("hOnUBBaN");
15658 hOffUBBaN.SetName("hOffUBBaN");
15659 hOnUBBaN.SetYTitle(title);
15660 hOffUBBaN.SetYTitle(title);
15661 BB.Divide(&hOnUBBaN,&hOffUBBaN,&hRatUBBaN,kFALSE,1);
15662 hRatUBBaN.SetName("hRatUBBaN");
15663 hRatUBBaN.SetYTitle("Ratio");
15664 }
15665
15666 // Store the produced histograms
15667 if (hOnSourceZ) fBurstHistos.Add(hOnSourceZ);
15668 if (hOffSourceZ) fBurstHistos.Add(hOffSourceZ);
15669 if (hOnSigSourceZ) fBurstHistos.Add(hOnSigSourceZ);
15670 if (hOnSigmaSource) fBurstHistos.Add(hOnSigmaSource);
15671 if (hOffSigmaSource) fBurstHistos.Add(hOffSigmaSource);
15672 if (hOnSigSigmaSource) fBurstHistos.Add(hOnSigSigmaSource);
15673 if (hOnSigmaReco) fBurstHistos.Add(hOnSigmaReco);
15674 if (hOffSigmaReco) fBurstHistos.Add(hOffSigmaReco);
15675 if (hOnSigSigmaReco) fBurstHistos.Add(hOnSigSigmaReco);
15676 if (hOnSigmaComb) fBurstHistos.Add(hOnSigmaComb);
15677 if (hOffSigmaComb) fBurstHistos.Add(hOffSigmaComb);
15678 if (hOnSigSigmaComb) fBurstHistos.Add(hOnSigSigmaComb);
15679 if (hOnE) fBurstHistos.Add(hOnE);
15680 if (hOffE) fBurstHistos.Add(hOffE);
15681 if (hOnSigE) fBurstHistos.Add(hOnSigE);
15682 if (hOna) fBurstHistos.Add(hOna);
15683 if (hOffa) fBurstHistos.Add(hOffa);
15684 if (hOnSiga) fBurstHistos.Add(hOnSiga);
15685 if (hOnCosa) fBurstHistos.Add(hOnCosa);
15686 if (hOffCosa) fBurstHistos.Add(hOffCosa);
15687 if (hOnSigcosa) fBurstHistos.Add(hOnSigcosa);
15688 if (hOnt) fBurstHistos.Add(hOnt);
15689 if (hOfft) fBurstHistos.Add(hOfft);
15690 if (hOnSigt) fBurstHistos.Add(hOnSigt);
15691 if (hOnta) fBurstHistos.Add(hOnta);
15692 if (hOffta) fBurstHistos.Add(hOffta);
15693 if (hOnSigta)fBurstHistos.Add(hOnSigta);
15694 if (hOnt && hOnBBt.GetEntries())
15695 {
15696 fBurstHistos.Add(hOnBBt.Clone());
15697 if (hOnBBtN) fBurstHistos.Add(hOnBBtN);
15698 }
15699 if (hOfft && hOffBBt.GetEntries())
15700 {
15701 fBurstHistos.Add(hOffBBt.Clone());
15702 if (hOffBBtN) fBurstHistos.Add(hOffBBtN);
15703 }
15704 if (hOnt && hOnUBBtN.GetEntries()) fBurstHistos.Add(hOnUBBtN.Clone());
15705 if (hOfft && hOffUBBtN.GetEntries()) fBurstHistos.Add(hOffUBBtN.Clone());
15706 if (hOnt && hOfft && hRatUBBtN.GetEntries()) fBurstHistos.Add(hRatUBBtN.Clone());
15707 if (hOnZt) fBurstHistos.Add(hOnZt);
15708 if (hOffZt) fBurstHistos.Add(hOffZt);
15709 if (hOnSigZt) fBurstHistos.Add(hOnSigZt);
15710 if (hOnZta) fBurstHistos.Add(hOnZta);
15711 if (hOffZta) fBurstHistos.Add(hOffZta);
15712 if (hOnSigZta) fBurstHistos.Add(hOnSigZta);
15713 if (hOnZt && hOnBBzt.GetEntries())
15714 {
15715 fBurstHistos.Add(hOnBBzt.Clone());
15716 if (hOnBBztN) fBurstHistos.Add(hOnBBztN);
15717 }
15718 if (hOffZt && hOffBBzt.GetEntries())
15719 {
15720 fBurstHistos.Add(hOffBBzt.Clone());
15721 if (hOffBBztN) fBurstHistos.Add(hOffBBztN);
15722 }
15723 if (hOnZt && hOnUBBztN.GetEntries()) fBurstHistos.Add(hOnUBBztN.Clone());
15724 if (hOffZt && hOffUBBztN.GetEntries()) fBurstHistos.Add(hOffUBBztN.Clone());
15725 if (hOnZt && hOffZt && hRatUBBztN.GetEntries()) fBurstHistos.Add(hRatUBBztN.Clone());
15726 if (hOna && hOnBBa.GetEntries())
15727 {
15728 fBurstHistos.Add(hOnBBa.Clone());
15729 if (hOnBBaN) fBurstHistos.Add(hOnBBaN);
15730 }
15731 if (hOffa && hOffBBa.GetEntries())
15732 {
15733 fBurstHistos.Add(hOffBBa.Clone());
15734 if (hOffBBaN) fBurstHistos.Add(hOffBBaN);
15735 }
15736 if (hOna && hOnUBBaN.GetEntries()) fBurstHistos.Add(hOnUBBaN.Clone());
15737 if (hOffa && hOffUBBaN.GetEntries()) fBurstHistos.Add(hOffUBBaN.Clone());
15738 if (hOna && hOffa && hRatUBBaN.GetEntries()) fBurstHistos.Add(hRatUBBaN.Clone());
15739
15740 // Make sure that also the auto-binned histograms have their axes ranges set
15741 Int_t nh=fBurstHistos.GetEntries();
15742 for (Int_t ih=0; ih<nh; ih++)
15743 {
15744 TH1* hx=(TH1*)fBurstHistos.At(ih);
15745 if (!hx) continue;
15746 hx->BufferEmpty(1);
15747
15748 name=hx->GetName();
15749
15750 if (name=="hTdiff")
15751 {
15752 binsize=hx->GetBinWidth(1);
15753 s.Form("Counts per %-.3g %-s",binsize,tu.Data());
15754 axis=hx->GetYaxis();
15755 if (axis) axis->SetTitle(s);
15756 }
15757
15758 if (name=="hAdiff" || name.Contains("Sigma"))
15759 {
15760 binsize=hx->GetBinWidth(1);
15761 s.Form("Counts per %-.3g degrees",binsize);
15762 axis=hx->GetYaxis();
15763 if (axis) axis->SetTitle(s);
15764 }
15765
15766 if (name=="hOnE" || name=="hOffE" || name=="hOnSigE")
15767 {
15768 binsize=hx->GetBinWidth(1);
15769 s.Form("Counts per %-.3g GeV",binsize);
15770 axis=hx->GetYaxis();
15771 if (axis) axis->SetTitle(s);
15772 }
15773 }
15774
15775 // Determination of the on-source and off-source event rates
15776 Float_t nOn=non;
15777 Float_t nOff=noff;
15778 Float_t Ton=DtwinOn*fTfact*float(fNgrbs); // Total on-source exposure time in seconds
15779 Float_t Toff=DtwinOff*fTfact*float(fNgrbs)*float(fNbkg); // Total off-source exposure time in seconds
15780 Float_t rateOn=nOn/(DtwinOn*fTfact);
15781 Float_t rateOff=nOff/(DtwinOff*fTfact);
15782
15783 // (Average) values per patch
15784 Float_t AvSolidangleOn=0;
15785 Float_t AvSolidangleOff=0;
15786 Float_t scale=fNgrbs;
15787 if (scale) AvSolidangleOn=fSolidangleOn/scale;
15788 scale=fNgrbs*fNbkg;
15789 if (scale) AvSolidangleOff=fSolidangleOff/scale;
15790
15791 // Create the simulated incoming signal Fluence vs. E histogram
15792 nsig=fBurstSigAeff.GetN();
15793 if (nsig && Ton)
15794 {
15795 TString nameS,titleS,nameF,titleF,nameE2F,titleE2F;
15796 nameS="hSigFluence";
15797 titleS="Stacked simulated incoming signal Fluence;Event energy [GeV];dN/(dEdA) [GeV^{-1} cm^{-2}]";
15798 nameF="hSigFlux";
15799 titleF="Simulated incoming signal Flux for a steady rate;Event energy [GeV];dN/(dEdAdt) [GeV^{-1} cm^{-2} s^{-1}]";
15800 nameE2F="hSigE2Flux";
15801 titleE2F="E-scaled simulated incoming signal Flux for a steady rate;Event energy [GeV];E^{2}dN/(dEdAdt) [GeV cm^{-2} s^{-1}]";
15802 TH1F* hS=(TH1F*)fBurstHistos.FindObject(nameS);
15803 TH1F* hF=(TH1F*)fBurstHistos.FindObject(nameF);
15804 TH1F* hE2F=(TH1F*)fBurstHistos.FindObject(nameE2F);
15805 if (hS)
15806 {
15807 delete hS;
15808 hS=new TH1F(nameS,titleS,100,0,-1);
15809 delete hF;
15810 hF=new TH1F(nameF,titleF,100,0,-1);
15811 delete hE2F;
15812 hE2F=new TH1F(nameE2F,titleE2F,100,0,-1);
15813 }
15814 else
15815 {
15816 hS=new TH1F(nameS,titleS,100,0,-1);
15817 fBurstHistos.Add(hS);
15818 hF=new TH1F(nameF,titleF,100,0,-1);
15819 fBurstHistos.Add(hF);
15820 hE2F=new TH1F(nameE2F,titleE2F,100,0,-1);
15821 fBurstHistos.Add(hE2F);
15822 }
15823
15824 hS->Sumw2();
15825 hF->Sumw2();
15826 hE2F->Sumw2();
15827
15828 Float_t E=0;
15829 Float_t Fluence=0;
15830 for (Int_t i=1; i<=nsig; i++)
15831 {
15832 Fluence=fBurstSigAeff.GetEntry(i,"Fluence");
15833 E=fBurstSigAeff.GetEntry(i,"E");
15834 if (Fluence>0)
15835 {
15836 hS->Fill(E,Fluence);
15837 hF->Fill(E,Fluence/Ton);
15838 hE2F->Fill(E,pow(E,2)*Fluence/Ton);
15839 }
15840 }
15841
15842 // Convert the histogram data into dN/dE
15843 // Flush the storage buffers to actually fill the histograms
15844 hS->BufferEmpty(1);
15845 hF->BufferEmpty(1);
15846 hE2F->BufferEmpty(1);
15847 Float_t binwidth=hS->GetBinWidth(1);
15848 if (binwidth>0)
15849 {
15850 hS->Scale(1./binwidth);
15851 hF->Scale(1./binwidth);
15852 hE2F->Scale(1./binwidth);
15853 }
15854 }
15855
15856 // Update internal statistics
15857 fBurstParameters->AddNamedSlot("TminOn");
15858 fBurstParameters->SetSignal(TminOn,"TminOn");
15859 fBurstParameters->AddNamedSlot("TmaxOn");
15860 fBurstParameters->SetSignal(TmaxOn,"TmaxOn");
15861 fBurstParameters->AddNamedSlot("TminOff");
15862 fBurstParameters->SetSignal(TminOff,"TminOff");
15863 fBurstParameters->AddNamedSlot("TmaxOff");
15864 fBurstParameters->SetSignal(TmaxOff,"TmaxOff");
15865 fBurstParameters->AddNamedSlot("DtwinOn");
15866 fBurstParameters->SetSignal(DtwinOn,"DtwinOn");
15867 fBurstParameters->AddNamedSlot("DtwinOff");
15868 fBurstParameters->SetSignal(DtwinOff,"DtwinOff");
15869 fBurstParameters->AddNamedSlot("NbkgWinOn");
15870 fBurstParameters->SetSignal(NbkgWinOn,"NbkgWinOn");
15871 fBurstParameters->AddNamedSlot("NbkgWinOff");
15872 fBurstParameters->SetSignal(NbkgWinOff,"NbkgWinOff");
15873 fBurstParameters->AddNamedSlot("TtotOn"); // The on-source total exposure time in sec.
15874 fBurstParameters->SetSignal(Ton,"TtotOn");
15875 fBurstParameters->AddNamedSlot("TtotOff"); // The off-source total exposure time ins sec.
15876 fBurstParameters->SetSignal(Toff,"TtotOff");
15877 fBurstParameters->AddNamedSlot("AvSolidangleOn"); // The average on-source solid angle
15878 fBurstParameters->SetSignal(AvSolidangleOn,"AvSolidangleOn");
15879 fBurstParameters->AddNamedSlot("AvSolidangleOff"); // The average off-source solid angle
15880 fBurstParameters->SetSignal(AvSolidangleOff,"AvSolidangleOff");
15881
15882 fBurstParameters->AddNamedSlot("rateOn");
15883 fBurstParameters->SetSignal(rateOn,"rateOn");
15884 fBurstParameters->AddNamedSlot("rateOff");
15885 fBurstParameters->SetSignal(rateOff,"rateOff");
15886
15887 // Update old parameters
15888 fBurstParameters->SetSignal(TminOn,"Tmin");
15889 fBurstParameters->SetSignal(TmaxOn,"Tmax");
15890 fBurstParameters->SetSignal(DtwinOn,"Dtwin");
15891 fBurstParameters->SetSignal(NbkgWinOn,"NbkgWin");
15892
15894}
15895
15897{
15903
15904 // Retrieve the needed parameters
15905 Int_t fNgrbs=TMath::Nint(fBurstParameters->GetSignal("Ngrbs"));
15906 Int_t fNbkg=TMath::Nint(fBurstParameters->GetSignal("Nbkg"));
15907 Int_t fBurstDataMode=TMath::Nint(fBurstParameters->GetSignal("BurstDataMode"));
15908 Int_t fNmugrb=TMath::Nint(fBurstParameters->GetSignal("Nmugrb"));
15909 Int_t fTunits=TMath::Nint(fBurstParameters->GetSignal("Tunits"));
15910 Float_t fTfact=fBurstParameters->GetSignal("Tfact");
15911 Float_t fSolidangleOn=fBurstParameters->GetSignal("SolidangleOn");
15912 Float_t fSolidangleOff=fBurstParameters->GetSignal("SolidangleOff");
15913 Float_t fEnergyOn=fBurstParameters->GetSignal("EnergyOn");
15914 Float_t fEnergyOff=fBurstParameters->GetSignal("EnergyOff");
15915 Float_t fEnergySig=fBurstParameters->GetSignal("EnergySig");
15916 Float_t fEnergyBkg=fEnergyOn-fEnergySig;
15917 Float_t fSensarea=fBurstParameters->GetSignal("Sensarea");
15918 Float_t fOmegaDecl=fBurstParameters->GetSignal("OmegaDecl");
15919
15920 TString tu="days";
15921 if (fTunits==1) tu="hours";
15922 if (fTunits==2) tu="sec";
15923 if (fTunits==3) tu="ns";
15924 if (fTunits==4) tu="ps";
15925
15926 Int_t non=fBurstOnMatch.GetN();
15927 Int_t noff=fBurstOffMatch.GetN();
15928 Int_t nsig=fBurstSignal.GetN();
15929
15930 // The time window sizes and the average number of background events in them
15931 Float_t DtwinOn=fBurstParameters->GetSignal("DtwinOn");
15932 Float_t DtwinOff=fBurstParameters->GetSignal("DtwinOff");
15933
15934 // Determination of the on-source and off-source event rates
15935 Float_t nOn=non;
15936 Float_t nOff=noff;
15937 Float_t nsigOn=nsig;
15938 Float_t nbkgOn=nOn-nsigOn;
15939 Float_t Ton=fBurstParameters->GetSignal("TtotOn"); // Total on-source exposure time in seconds
15940 Float_t Toff=fBurstParameters->GetSignal("TtotOff"); // Total off-source exposure time in seconds
15941
15942 // (Average) values per patch
15943 Float_t TwinOn=DtwinOn*fTfact;
15944 Float_t TwinOff=DtwinOff*fTfact;
15945 Float_t AvSolidangleOn=fBurstParameters->GetSignal("AvSolidangleOn");
15946 Float_t AvSolidangleOff=fBurstParameters->GetSignal("AvSolidangleOff");
15947 Float_t AvNon=0;
15948 Float_t AvNoff=0;
15949 Float_t AvRon=0;
15950 Float_t AvRoff=0;
15951 Float_t AvEon=0;
15952 Float_t AvEoff=0;
15953 Float_t AvNsigOn=0;
15954 Float_t AvNbkgOn=0;
15955 Float_t AvRsigOn=0;
15956 Float_t AvRbkgOn=0;
15957 Float_t AvEsigOn=0;
15958 Float_t AvEbkgOn=0;
15959 Float_t scale=fNgrbs;
15960 if (scale)
15961 {
15962 AvNon=nOn/scale;
15963 AvRon=nOn/Ton;
15964 AvEon=fEnergyOn/scale;
15965 AvNsigOn=nsigOn/scale;
15966 AvNbkgOn=nbkgOn/scale;
15967 AvRsigOn=nsigOn/Ton;
15968 AvRbkgOn=nbkgOn/Ton;
15969 AvEsigOn=fEnergySig/scale;
15970 AvEbkgOn=fEnergyBkg/scale;
15971 }
15972 scale=fNgrbs*fNbkg;
15973 if (scale)
15974 {
15975 AvNoff=nOff/scale;
15976 AvRoff=nOff/Toff;
15977 AvEoff=fEnergyOff/scale;
15978 }
15979
15980 // Statistics of the stacked event samples
15981 printf("\n *%-s::ListBurstDataStats* Statistics of the stacked observed event samples. \n",ClassName());
15982 printf(" Solid angle coverage corresponding to the selected RA and DEC range : %-g steradian \n",fOmegaDecl);
15983 printf(" Integrated on-source exposure time of the %-i stacked time windows : %-g %-s \n",fNgrbs,Ton/fTfact,tu.Data());
15984 printf(" Integrated off-source exposure time of the %-i*%-i stacked time windows : %-g %-s \n",fNgrbs,fNbkg,Toff/fTfact,tu.Data());
15985 printf(" Total accumulated on-source solid angle : %-g sr in %-i stacked patches --> Average per patch : %-g sr \n",fSolidangleOn,fNgrbs,AvSolidangleOn);
15986 printf(" Total accumulated off-source solid angle : %-g sr in %-i*%-i stacked patches --> Average per patch : %-g sr \n",fSolidangleOff,fNgrbs,fNbkg,AvSolidangleOff);
15987 if (fSensarea>0) printf(" Area covered c.q. overlooked by the detector sensors : %-g m^2. \n",fSensarea);
15988 fSensarea*=1e4; // Convert to cm^2
15989
15990 printf(" *On source* Total number of recorded on-source events : %-g --> Average per patch : %-g events. \n",nOn,AvNon);
15991 printf(" --- Average recorded values per on-source patch --- \n");
15992 printf(" Steady event rate during the time window : %-g Hz",AvRon);
15993 if (AvSolidangleOn) printf(" --> %-g Hz sr^-1",AvRon/AvSolidangleOn);
15994 printf("\n");
15995 if (fSensarea>0)
15996 {
15997 printf(" Particle fluence : %-g cm^-2",AvNon/fSensarea);
15998 if (AvSolidangleOn) printf(" --> %-g cm^-2 sr^-1",AvNon/(fSensarea*AvSolidangleOn));
15999 printf("\n");
16000 printf(" Particle flux : %-g cm^-2 s^-1",AvRon/fSensarea);
16001 if (AvSolidangleOn) printf(" --> Intensity : %-g cm^-2 s^-1 sr^-1",AvRon/(fSensarea*AvSolidangleOn));
16002 printf("\n");
16003 }
16004 printf(" Cumulated energy : %-g GeV",AvEon);
16005 if (AvSolidangleOn) printf(" --> %-g GeV sr^-1",AvEon/AvSolidangleOn);
16006 printf("\n");
16007 printf(" Power : %-g GeV/s",AvEon/TwinOn);
16008 if (AvSolidangleOn) printf(" --> %-g GeV s^-1 sr^-1",AvEon/(TwinOn*AvSolidangleOn));
16009 printf("\n");
16010 if (fSensarea>0)
16011 {
16012 printf(" Energy fluence : %-g GeV cm^-2",AvEon/fSensarea);
16013 if (AvSolidangleOn) printf(" --> %-g GeV cm^-2 sr^-1",AvEon/(fSensarea*AvSolidangleOn));
16014 printf("\n");
16015 printf(" Energy flux : %-g GeV cm^-2 s^-1",AvEon/(fSensarea*TwinOn));
16016 if (AvSolidangleOn) printf(" --> Intensity : %-g GeV cm^-2 s^-1 sr^-1",AvEon/(fSensarea*TwinOn*AvSolidangleOn));
16017 printf("\n");
16018 }
16019
16020 if (fNbkg)
16021 {
16022 printf(" *Off source* Total number of recorded off-source (background) events : %-g --> Average per patch : %-g events. \n",nOff,AvNoff);
16023 printf(" --- Average recorded values per off-source patch --- \n");
16024 printf(" Steady event rate during the time window : %-g Hz",AvRoff);
16025 if (AvSolidangleOff) printf(" --> %-g Hz sr^-1",AvRoff/AvSolidangleOff);
16026 printf("\n");
16027 if (fSensarea>0)
16028 {
16029 printf(" Particle fluence : %-g cm^-2",AvNoff/fSensarea);
16030 if (AvSolidangleOff) printf(" --> %-g cm^-2 sr^-1",AvNoff/(fSensarea*AvSolidangleOff));
16031 printf("\n");
16032 printf(" Particle flux : %-g cm^-2 s^-1",AvRoff/fSensarea);
16033 if (AvSolidangleOff) printf(" --> Intensity : %-g cm^-2 s^-1 sr^-1",AvRoff/(fSensarea*AvSolidangleOff));
16034 printf("\n");
16035 }
16036 printf(" Cumulated energy : %-g GeV",AvEoff);
16037 if (AvSolidangleOff) printf(" --> %-g GeV sr^-1",AvEoff/AvSolidangleOff);
16038 printf("\n");
16039 printf(" Power : %-g GeV/s",AvEoff/TwinOff);
16040 if (AvSolidangleOff) printf(" --> %-g GeV s^-1 sr^-1",AvEoff/(TwinOn*AvSolidangleOff));
16041 printf("\n");
16042 if (fSensarea>0)
16043 {
16044 printf(" Energy fluence : %-g GeV cm^-2",AvEoff/fSensarea);
16045 if (AvSolidangleOff) printf(" --> %-g GeV cm^-2 sr^-1",AvEoff/(fSensarea*AvSolidangleOff));
16046 printf("\n");
16047 printf(" Energy flux : %-g GeV cm^-2 s^-1",AvEoff/(fSensarea*TwinOff));
16048 if (AvSolidangleOff) printf(" --> Intensity : %-g GeV cm^-2 s^-1 sr^-1",AvEoff/(fSensarea*TwinOff*AvSolidangleOff));
16049 printf("\n");
16050 }
16051 }
16052
16053 // On-source signal and background info is only available for simulated data
16054 if (!fBurstDataMode)
16055 {
16056 printf(" -(Unknown)- Total number of injected on-source signal events : %-i",fNmugrb);
16057 if (fNgrbs) printf(" --> Average per patch : %-g events.",float(fNmugrb)/float(fNgrbs));
16058 printf("\n");
16059 printf(" Total number of recorded on-source signal events : %-g",nsigOn);
16060 if (fNgrbs) printf(" --> Average per patch : %-g events.",nsigOn/float(fNgrbs));
16061 printf("\n");
16062 printf(" Total number of recorded on-source bkg events : %-g",nbkgOn);
16063 if (fNgrbs) printf(" --> Average per patch : %-g events.",nbkgOn/float(fNgrbs));
16064 printf("\n");
16065
16066 printf(" --- Average signal values per on-source patch --- \n");
16067 printf(" Steady event rate during the time window : %-g Hz",AvRsigOn);
16068 if (AvSolidangleOn) printf(" --> %-g Hz sr^-1",AvRsigOn/AvSolidangleOn);
16069 printf("\n");
16070 if (fSensarea>0)
16071 {
16072 printf(" Particle fluence : %-g cm^-2",AvNsigOn/fSensarea);
16073 if (AvSolidangleOn) printf(" --> %-g cm^-2 sr^-1",AvNsigOn/(fSensarea*AvSolidangleOn));
16074 printf("\n");
16075 printf(" Particle flux : %-g cm^-2 s^-1",AvRsigOn/fSensarea);
16076 if (AvSolidangleOn) printf(" --> Intensity : %-g cm^-2 s^-1 sr^-1",AvRsigOn/(fSensarea*AvSolidangleOn));
16077 printf("\n");
16078 }
16079 printf(" Cumulated energy : %-g GeV",AvEsigOn);
16080 if (AvSolidangleOn) printf(" --> %-g GeV sr^-1",AvEsigOn/AvSolidangleOn);
16081 printf("\n");
16082 printf(" Power : %-g GeV/s",AvEsigOn/TwinOn);
16083 if (AvSolidangleOn) printf(" --> %-g GeV s^-1 sr^-1",AvEsigOn/(TwinOn*AvSolidangleOn));
16084 printf("\n");
16085 if (fSensarea>0)
16086 {
16087 printf(" Energy fluence : %-g GeV cm^-2",AvEsigOn/fSensarea);
16088 if (AvSolidangleOn) printf(" --> %-g GeV cm^-2 sr^-1",AvEsigOn/(fSensarea*AvSolidangleOn));
16089 printf("\n");
16090 printf(" Energy flux : %-g GeV cm^-2 s^-1",AvEsigOn/(fSensarea*TwinOn));
16091 if (AvSolidangleOn) printf(" --> Intensity : %-g GeV cm^-2 s^-1 sr^-1",AvEsigOn/(fSensarea*TwinOn*AvSolidangleOn));
16092 printf("\n");
16093 }
16094 printf(" --- Average background values per on-source patch --- \n");
16095 printf(" Steady event rate during the time window : %-g Hz",AvRbkgOn);
16096 if (AvSolidangleOn) printf(" --> %-g Hz sr^-1",AvRbkgOn/AvSolidangleOn);
16097 printf("\n");
16098 if (fSensarea>0)
16099 {
16100 printf(" Particle fluence : %-g cm^-2",AvNbkgOn/fSensarea);
16101 if (AvSolidangleOn) printf(" --> %-g cm^-2 sr^-1",AvNbkgOn/(fSensarea*AvSolidangleOn));
16102 printf("\n");
16103 printf(" Particle flux : %-g cm^-2 s^-1",AvRbkgOn/fSensarea);
16104 if (AvSolidangleOn) printf(" --> Intensity : %-g cm^-2 s^-1 sr^-1",AvRbkgOn/(fSensarea*AvSolidangleOn));
16105 printf("\n");
16106 }
16107 printf(" Cumulated energy : %-g GeV",AvEbkgOn);
16108 if (AvSolidangleOn) printf(" --> %-g GeV sr^-1",AvEbkgOn/AvSolidangleOn);
16109 printf("\n");
16110 printf(" Power : %-g GeV/s",AvEbkgOn/TwinOn);
16111 if (AvSolidangleOn) printf(" --> %-g GeV s^-1 sr^-1",AvEbkgOn/(TwinOn*AvSolidangleOn));
16112 printf("\n");
16113 if (fSensarea>0)
16114 {
16115 printf(" Energy fluence : %-g GeV cm^-2",AvEbkgOn/fSensarea);
16116 if (AvSolidangleOn) printf(" --> %-g GeV cm^-2 sr^-1",AvEbkgOn/(fSensarea*AvSolidangleOn));
16117 printf("\n");
16118 printf(" Energy flux : %-g GeV cm^-2 s^-1",AvEbkgOn/(fSensarea*TwinOn));
16119 if (AvSolidangleOn) printf(" --> Intensity : %-g GeV cm^-2 s^-1 sr^-1",AvEbkgOn/(fSensarea*TwinOn*AvSolidangleOn));
16120 printf("\n");
16121 }
16122 }
16123 printf("\n");
16124}
16125
16126NcSample NcAstrolab::GetBurstDataSample(TString type,TString data) const
16127{
16142
16143 if (type=="On")
16144 {
16145 if (data=="Reco") return fBurstOnReco;
16146 if (data=="Match") return fBurstOnMatch;
16147 if (data=="Aeff") return fBurstOnAeff;
16148 }
16149
16150 if (type=="Off")
16151 {
16152 if (data=="Reco") return fBurstOffReco;
16153 if (data=="Match") return fBurstOffMatch;
16154 if (data=="Aeff") return fBurstOffAeff;
16155 }
16156
16157 if (type=="Sig")
16158 {
16159 if (data=="Reco") return fBurstSigReco;
16160 if (data=="Match") return fBurstSignal;
16161 if (data=="Aeff") return fBurstSigAeff;
16162 }
16163
16164 printf(" *%-s::GetBurstDataSample* Inconsitent input type=%-s data=%-s \n",ClassName(),type.Data(),data.Data());
16165 NcSample sx;
16166 return sx;
16167}
16168
16169void NcAstrolab::MatchBurstData(NcDevice& matches,Int_t i1,Int_t i2,Int_t itype,Int_t j1,Int_t j2,Int_t jtype)
16170{
16265
16266 // Indicate that this will be a burst analysis on real data
16267 fBurstParameters->AddNamedSlot("BurstDataMode");
16268 fBurstParameters->SetSignal(1,"BurstDataMode");
16269
16270 Float_t fAngresfix=fBurstParameters->GetSignal("Angresfix");
16271 Int_t fRecoangle=TMath::Nint(fBurstParameters->GetSignal("Recoangle"));
16272 Int_t fSumsigmas=TMath::Nint(fBurstParameters->GetSignal("Sumsigmas"));
16273 Int_t fTunits=TMath::Nint(fBurstParameters->GetSignal("Tunits"));
16274 Float_t fTmin=fBurstParameters->GetSignal("Tmin");
16275 Float_t fTmax=fBurstParameters->GetSignal("Tmax");
16276 Float_t fDawin=fBurstParameters->GetSignal("Dawin");
16277 Int_t fDatype=TMath::Nint(fBurstParameters->GetSignal("Datype"));
16278 Float_t fMaxsigmatot=fBurstParameters->GetSignal("Maxsigmatot");
16279 Int_t fNbkg=TMath::Nint(fBurstParameters->GetSignal("Nbkg"));
16280
16281 // Update internal statistics to account for objects introduced by hand
16282 Int_t fNgrbs=GetNsignals(0);
16283 Int_t fNevts=GetNsignals(1);
16284 fBurstParameters->AddNamedSlot("Ngrbs");
16285 fBurstParameters->AddNamedSlot("Nevts");
16286 fBurstParameters->SetSignal(fNgrbs,"Ngrbs");
16287 fBurstParameters->SetSignal(fNevts,"Nevts");
16288
16289 // Initialize generic histograms for analysis
16291
16292 TString tu="d";
16293 if (fTunits==1) tu="hrs";
16294 if (fTunits==2) tu="s";
16295 if (fTunits==3) tu="ns";
16296 if (fTunits==4) tu="ps";
16297
16298 // Initialize the Device/Hit structure to contain the correlation info
16299 matches.Reset(1);
16300 matches.SetHitCopy(1);
16301
16302 TString name="Matches";
16303 TString title="Space and time matchings of NcAstrolab stored signals";
16304 matches.SetNameTitle(name,title);
16305 TString tux=tu;
16306 if (tu=="d") tux="days";
16307 if (tu=="hrs") tux="hours";
16308 if (tu=="s") tux="sec";
16309 TString namedamin="psimin in deg";
16310 TString namedtmin="dtmin in ";
16311 namedtmin+=tux;
16312 matches.AddNamedSlot(namedamin);
16313 matches.AddNamedSlot(namedtmin);
16314 matches.AddNamedSlot("ipsi");
16315 matches.AddNamedSlot("idt");
16316
16317 NcSignal data;
16318 TString nameda="psi in deg";
16319 TString namedt="t2-t1 in ";
16320 namedt+=tux;
16321 data.AddNamedSlot("type1");
16322 data.AddNamedSlot("index1");
16323 data.AddNamedSlot("type2");
16324 data.AddNamedSlot("index2");
16325 data.AddNamedSlot(nameda);
16326 data.AddNamedSlot(namedt);
16327
16328 if ((!itype || !jtype) && !fRefs)
16329 {
16330 printf(" *%-s::MatchBurstData* Error: itype=%-i jtype=%-i but no reference signals are present. \n",ClassName(),itype,jtype);
16331 return;
16332 }
16333
16334 if ((itype || jtype) && !fSigs)
16335 {
16336 printf(" *%-s::MatchBurstData* Error: itype=%-i jtype=%-i but no measurements are present. \n",ClassName(),itype,jtype);
16337 return;
16338 }
16339
16340 Int_t nrefs=0;
16341 if (fRefs) nrefs=fRefs->GetSize();
16342 Int_t nsigs=0;
16343 if (fSigs) nsigs=fSigs->GetSize();
16344
16345 // Make input data consistent with conventions
16346 if (itype) itype=1;
16347 if (jtype) jtype=1;
16348 if (!itype)
16349 {
16350 if (i2<1 || i2>nrefs) i2=nrefs;
16351 }
16352 else
16353 {
16354 if (i2<1 || i2>nsigs) i2=nsigs;
16355 }
16356 if (!jtype)
16357 {
16358 if (j2<1 || j2>nrefs) j2=nrefs;
16359 }
16360 else
16361 {
16362 if (j2<1 || j2>nsigs) j2=nsigs;
16363 }
16364
16365 if (i1<1 || j1<1 || i1>i2 || j1>j2)
16366 {
16367 printf(" *%-s::MatchBurstData* Inconsistent parameters: i1=%-i i2=%-i itype=%-i j1=%-i j2=%-i jtype=%-i. \n",ClassName(),i1,i2,itype,j1,j2,jtype);
16368 return;
16369 }
16370
16371 if (fDatype==1 && fMaxsigmatot<0)
16372 {
16373 printf(" *%-s::MatchBurstData* Incompatible parameter settings Datype=%-i Maxsigmatot=%-g \n",ClassName(),fDatype,fMaxsigmatot);
16374 printf(" === No matching analysis will be performed === \n");
16375 }
16376
16377 // The number of actually stored items
16378 Int_t ni=GetNsignals(itype);
16379 Int_t nj=GetNsignals(jtype);
16380
16381 // Additional text for histo titles to indicate scrambling of the corresponding data
16382 TString scrt=""; // Time scrambling
16383 TString scrp=""; // Position scrambling
16384 if (fTscmode>0) scrt="(scrambled)";
16385 if (fRscmode>0 || fTscmode==3) scrp="(scrambled)";
16386
16387 // The auto binned event-burst time difference histo for the full selected sample
16388 Int_t nbins=10000;
16389 title.Form("Time difference %-s between events and bursts for the full selected dataset;Tevent-Tburst in %-s;Counts",scrt.Data(),tux.Data());
16390 TH1F* hTdiff=new TH1F("hTdiff",title,nbins,1,0);
16391 if (ni && nj) hTdiff->SetBuffer(ni*nj);
16392
16393 // The auto binned event-burst angular difference histo for the full selected sample
16394 nbins=100;
16395 title.Form("Angular separation %-s between events and bursts for the full selected dataset;Opening angle in degrees;Counts",scrp.Data());
16396 TH1F* hAdiff=new TH1F("hAdiff",title,nbins,1,0);
16397 if (ni && nj) hAdiff->SetBuffer(ni*nj);
16398
16399 // Recording of the cumulated on-source reconstructed event energy
16400 fBurstParameters->AddNamedSlot("EnergyOn");
16401 fBurstParameters->AddNamedSlot("EnergyOff");
16402
16403 Double_t dang,dtime,diftheta;
16404 Int_t ix=0;
16405 Int_t jx=0;
16406 NcSignal* sxi=0;
16407 NcSignal* sxj=0;
16408 NcSignal* sxgrb=0;
16409 NcSignal* sxevt=0;
16410 Float_t sigmai=0;
16411 Float_t sigmaj=0;
16412 Float_t sigmagrb=0;
16413 Float_t sigmareco=0;
16414 Float_t sigmatot=0;
16415 Int_t id=0;
16416 Double_t dangmin=0;
16417 Double_t dtmin=0;
16418 Int_t idamin=0;
16419 Int_t idtmin=0;
16420 Bool_t first=kTRUE;
16421 Double_t dangmax=-1;
16422 Float_t Ereco=0;
16423 Float_t thlow=0;
16424 Float_t thup=0;
16425 Float_t thetagrb=0;
16426 Float_t solidangle=0;
16427 Int_t grbtype=0;
16428 Int_t evttype=0;
16429 Int_t k1=0;
16430 Int_t k2=0;
16431 Float_t zgrb=0;
16432 Int_t idx=0;
16433 NcTimestamp* tx=0;
16434 Nc3Vector rmu;
16435 Float_t thetamu=0;
16436 TH2* hAeffProfile=(TH2*)fBurstHistos.FindObject("hAeffProfile");
16437 Int_t gbin=0;
16438 Double_t Aeff=0;
16439 Double_t Fluence=0;
16440 for (Int_t bkgpatch=0; bkgpatch<=fNbkg; bkgpatch++) // On-source and Off-source patches
16441 {
16442 if (bkgpatch && !fTscmode && !fRscmode) break; // No background data without time and/or position scrambling
16443
16444 for (Int_t i=i1; i<=i2; i++)
16445 {
16446 sxi=GetSignal(i,itype);
16447 if (!sxi) continue;
16448
16449 sigmai=sxi->GetSignal("csigma");
16450
16451 if (itype && !fRecoangle) sigmai=fAngresfix;
16452
16453 for (Int_t j=j1; j<=j2; j++)
16454 {
16455 // Skip matching a signal with itself
16456 if (itype==jtype && i==j) continue;
16457
16458 sxj=GetSignal(j,jtype);
16459 if (!sxj) continue;
16460
16461 sigmaj=sxj->GetSignal("csigma");
16462
16463 if (jtype && !fRecoangle) sigmaj=fAngresfix;
16464
16465 if (itype==jtype) // Self correlations
16466 {
16467 sigmagrb=sigmai;
16468 sxgrb=sxi;
16469 grbtype=itype;
16470 sigmareco=sigmaj;
16471 sxevt=sxj;
16472 evttype=jtype;
16473 }
16474 else // Correlations between sources and measurements
16475 {
16476 if (itype)
16477 {
16478 sigmareco=sigmai;
16479 sxevt=sxi;
16480 evttype=itype;
16481 sigmagrb=sigmaj;
16482 sxgrb=sxj;
16483 grbtype=jtype;
16484 }
16485 else
16486 {
16487 sigmagrb=sigmai;
16488 sxgrb=sxi;
16489 grbtype=itype;
16490 sigmareco=sigmaj;
16491 sxevt=sxj;
16492 evttype=jtype;
16493 }
16494 }
16495
16496 sigmatot=-1;
16497 if (fSumsigmas==-1) sigmatot=sigmareco;
16498 if (fSumsigmas==0) sigmatot=sigmagrb;
16499 if (fSumsigmas==1) sigmatot=sigmagrb+sigmareco;
16500 if (fSumsigmas==2) sigmatot=sqrt(sigmagrb*sigmagrb+sigmareco*sigmareco);
16501
16502 dangmax=-1;
16503 if (!fDatype) dangmax=fabs(fDawin);
16504 if (fDatype==1)
16505 {
16506 dangmax=0;
16507 if (fMaxsigmatot>0) dangmax=fabs(fDawin*fMaxsigmatot);
16508 }
16509 if (fDatype==2)
16510 {
16511 if (sigmatot>=0) dangmax=fabs(fDawin*sigmatot);
16512 }
16513
16514 // Flag incompatible input for sigma summation
16515 if (fDatype==1 && fMaxsigmatot<0) dangmax=-1;
16516
16517 ix=i;
16518 if (itype) ix=-i;
16519 jx=j;
16520 if (jtype) jx=-j;
16521
16522 if (tu!="hrs")
16523 {
16524 dang=GetSeparation(ix,jx,"deg",dtime,tu,1,bkgpatch,&diftheta);
16525 }
16526 else
16527 {
16528 dang=GetSeparation(ix,jx,"deg",dtime,"s",1,bkgpatch,&diftheta);
16529 dtime=dtime/3600.;
16530 }
16531
16532 if (!bkgpatch) // On-source data
16533 {
16534 // Fill the time difference histogram for full selected dataset
16535 if (hTdiff) hTdiff->Fill(dtime);
16536
16537 // Fill the angular difference histogram for full selected dataset
16538 if (hAdiff) hAdiff->Fill(dang);
16539
16540 // Initialize the On-source total solid angle for this source
16541 if (dangmax>=0 && !(sxgrb->GetSlotIndex("OmegaOn")))
16542 {
16543 sxgrb->AddNamedSlot("OmegaOn");
16544 if (fDawin<0) // Local zenith band
16545 {
16546 thlow=thetagrb-0.5*dangmax;
16547 thup=thetagrb+0.5*dangmax;
16548 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
16549 }
16550 else // Circle around GRB position
16551 {
16552 thlow=0;
16553 thup=dangmax;
16554 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
16555 }
16556 sxgrb->SetSignal(solidangle,"OmegaOn");
16557 }
16558 }
16559 else // Off-source c.q. background data
16560 {
16561 // Initialize the Off-source total solid angle for this source
16562 if (dangmax>=0 && !(sxgrb->GetSlotIndex("OmegaOff")))
16563 {
16564 sxgrb->AddNamedSlot("OmegaOff");
16565 if (fDawin<0) // Local zenith band
16566 {
16567 thlow=thetagrb-0.5*dangmax;
16568 thup=thetagrb+0.5*dangmax;
16569 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
16570 }
16571 else // Circle around GRB position
16572 {
16573 thlow=0;
16574 thup=dangmax;
16575 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
16576 }
16577 sxgrb->SetSignal(solidangle,"OmegaOff");
16578 }
16579 }
16580
16581 if (fDatype>=0)
16582 {
16583 if (fDawin<0) // Declination band
16584 {
16585 if (diftheta<thlow || diftheta>thup) continue;
16586 }
16587 else // Circle around the GRB
16588 {
16589 if (fabs(dang)>dangmax) continue;
16590 }
16591 }
16592
16593 if (fTmax>fTmin && (dtime<fTmin || dtime>fTmax)) continue;
16594
16595 if (!bkgpatch) // On-source data
16596 {
16597 // Tag this source of having an on-source matching event
16598 if (!(sxgrb->GetSlotIndex("HasMatchOn")))
16599 {
16600 sxgrb->AddNamedSlot("HasMatchOn");
16601 sxgrb->SetSignal(1,"HasMatchOn");
16602 }
16603
16604 data.Reset();
16605 name="Object1=";
16606 name+=sxi->GetName();
16607 title="Object2=";
16608 title+=sxj->GetName();
16609 id++;
16610 data.SetNameTitle(name,title);
16611 data.SetUniqueID(id);
16612 data.SetSignal(itype,"type1");
16613 data.SetSignal(i,"index1");
16614 data.SetSignal(jtype,"type2");
16615 data.SetSignal(j,"index2");
16616 data.SetSignal(dtime,namedt);
16617 data.SetSignal(dang,nameda);
16618 matches.AddHit(data);
16619
16620 // Update the maximum encountered dynamic On-source solid angle for this source
16621 if (fDatype==2)
16622 {
16623 if (fDawin<0) // Local zenith band
16624 {
16625 thlow=thetagrb-0.5*dangmax;
16626 thup=thetagrb+0.5*dangmax;
16627 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
16628 }
16629 else // Circle around GRB position
16630 {
16631 thlow=0;
16632 thup=dangmax;
16633 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
16634 }
16635 if (solidangle>sxgrb->GetSignal("OmegaOn")) sxgrb->SetSignal(solidangle,"OmegaOn");
16636 }
16637 }
16638 else // Off-source c.q. background data
16639 {
16640 // Tag this source of having an off-source matching event
16641 if (!(sxgrb->GetSlotIndex("HasMatchOff")))
16642 {
16643 sxgrb->AddNamedSlot("HasMatchOff");
16644 sxgrb->SetSignal(1,"HasMatchOff");
16645 }
16646
16647 // Update the maximum encountered dynamic Off-source solid angle for this source
16648 if (fDatype==2)
16649 {
16650 if (fDawin<0) // Local zenith band
16651 {
16652 thlow=thetagrb-0.5*dangmax;
16653 thup=thetagrb+0.5*dangmax;
16654 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
16655 }
16656 else // Circle around GRB position
16657 {
16658 thlow=0;
16659 thup=dangmax;
16660 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
16661 }
16662 if (solidangle>sxgrb->GetSignal("OmegaOff")) sxgrb->SetSignal(solidangle,"OmegaOff");
16663 }
16664 }
16665
16666 // Fill the histograms for the matching data
16667 if (!bkgpatch) // On-source data
16668 {
16669 Ereco=sxevt->GetSignal("E");
16670 zgrb=sxgrb->GetSignal("z");
16671 fBurstOnReco.Enter(zgrb,sigmagrb,sigmareco,sigmatot);
16672 fBurstOnMatch.Enter(Ereco,dtime,dang,dtime/(zgrb+1.));
16673 fBurstParameters->AddSignal(Ereco,"EnergyOn");
16674 if (hAeffProfile)
16675 {
16676 nbins=(hAeffProfile->GetNbinsX())*(hAeffProfile->GetNbinsY());
16677 idx=GetSignalIndex(sxevt,evttype);
16678 if (idx>0)
16679 {
16680 tx=sxevt->GetTimestamp();
16681 GetSignal(rmu,"loc","T",tx,idx,evttype);
16682 thetamu=rmu.GetX(2,"sph","rad");
16683 gbin=hAeffProfile->FindFixBin(log10(Ereco),cos(thetamu));
16684 if (gbin>0 && gbin<nbins+1)
16685 {
16686 Aeff=hAeffProfile->GetBinContent(gbin);
16687 if (Aeff>0)
16688 {
16689 Fluence=1./Aeff;
16690 fBurstOnAeff.Enter(Aeff,Fluence,Ereco,dang);
16691 }
16692 }
16693 }
16694 }
16695
16696 // Record the data for the minimal encountered opening angle
16697 if (first || fabs(dang)<dangmin)
16698 {
16699 dangmin=fabs(dang);
16700 idamin=id;
16701 }
16702
16703 // Record the data for the minimal encountered time difference
16704 if (first || fabs(dtime)<fabs(dtmin))
16705 {
16706 dtmin=dtime;
16707 idtmin=id;
16708 }
16709
16710 first=kFALSE;
16711 }
16712 else // Off-source c.q. backgound data
16713 {
16714 Ereco=sxevt->GetSignal("E");
16715 zgrb=sxgrb->GetSignal("z");
16716 fBurstOffReco.Enter(zgrb,sigmagrb,sigmareco,sigmatot);
16717 fBurstOffMatch.Enter(Ereco,dtime,dang,dtime/(zgrb+1.));
16718 fBurstParameters->AddSignal(Ereco,"EnergyOff");
16719 if (hAeffProfile)
16720 {
16721 nbins=(hAeffProfile->GetNbinsX())*(hAeffProfile->GetNbinsY());
16722 idx=GetSignalIndex(sxevt,evttype);
16723 if (idx>0)
16724 {
16725 tx=sxevt->GetTimestamp();
16726 GetSignal(rmu,"loc","T",tx,idx,evttype);
16727 thetamu=rmu.GetX(2,"sph","rad");
16728 gbin=hAeffProfile->FindFixBin(log10(Ereco),cos(thetamu));
16729 if (gbin>0 && gbin<nbins+1)
16730 {
16731 Aeff=hAeffProfile->GetBinContent(gbin);
16732 if (Aeff>0)
16733 {
16734 Fluence=1./Aeff;
16735 fBurstOffAeff.Enter(Aeff,Fluence,Ereco,dang);
16736 }
16737 }
16738 }
16739 }
16740 }
16741 } // End of the j-loop
16742 } // End of the i-loop
16743 } // End of loop over the patches
16744
16745 // Store the filled histograms in the storage container
16746 if (hTdiff->GetEntries()) fBurstHistos.Add(hTdiff);
16747 if (hAdiff->GetEntries()) fBurstHistos.Add(hAdiff);
16748
16749 // Recording of the On-source and Off-source total stacked solid angles
16750 name="SolidangleOn";
16751 fBurstParameters->AddNamedSlot(name);
16752 fBurstParameters->SetSignal(0,name);
16753 name="SolidangleOff";
16754 fBurstParameters->AddNamedSlot(name);
16755 fBurstParameters->SetSignal(0,name);
16756 if (itype==jtype) // Self correlations
16757 {
16758 grbtype=itype;
16759 k1=i1;
16760 k2=i2;
16761 }
16762 else // Correlations between sources and measurements
16763 {
16764 if (itype)
16765 {
16766 grbtype=jtype;
16767 k1=j1;
16768 k2=j2;
16769 }
16770 else
16771 {
16772 grbtype=itype;
16773 k1=i1;
16774 k2=i2;
16775 }
16776 }
16777 // Loop over all grbs in the selection
16778 for (Int_t k=k1; k<=k2; k++)
16779 {
16780 sxgrb=GetSignal(k,grbtype);
16781 if (!sxgrb) continue;
16782
16783 solidangle=sxgrb->GetSignal("OmegaOn");
16784 fBurstParameters->AddSignal(solidangle,"SolidangleOn");
16785
16786 solidangle=sxgrb->GetSignal("OmegaOff");
16787 fBurstParameters->AddSignal(solidangle*float(fNbkg),"SolidangleOff");
16788 }
16789
16790 // Store the data for the minimal encountered opening angle and time difference
16791 matches.SetSignal(dangmin,namedamin);
16792 matches.SetSignal(dtmin,namedtmin);
16793 matches.SetSignal(idamin,"ipsi");
16794 matches.SetSignal(idtmin,"idt");
16795
16796 // Determine and list the burst statistics
16798}
16799
16800void NcAstrolab::MatchBurstData(NcDevice& matches,TString name,Int_t itype,Int_t j1,Int_t j2,Int_t jtype)
16801{
16900
16901 Int_t i=GetSignalIndex(name,itype);
16902
16903 if (i==-1) // Add the info for the requested Solar system object if not already stored
16904 {
16905 SetSolarSystem(name,0,itype);
16906 i=GetSignalIndex(name,itype);
16907 if (i>0) fSolUpdate=1;
16908 }
16909
16910 if (i<1)
16911 {
16912 printf(" *%-s::MatchBurstData* Object %-s not found for itype=%-i. \n",ClassName(),name.Data(),itype);
16913 }
16914 else
16915 {
16916 MatchBurstData(matches,i,i,itype,j1,j2,jtype);
16917 }
16918
16919 fSolUpdate=0;
16920}
16921
16923{
16935
16936 // Retrieve the burst analysis data mode
16937 // mode : 0 --> Analysis based on simulated data via GenBurstSignals()
16938 // 1 --> Analysis based on real data via MatchBurstData()
16939 Int_t mode=TMath::Nint(fBurstParameters->GetSignal("BurstDataMode"));
16940
16941 // Retreive the needed parameters
16942 Float_t fT90min=fBurstParameters->GetSignal("T90min");
16943 Float_t fT90max=fBurstParameters->GetSignal("T90max");
16944 Float_t fAlphasig=fBurstParameters->GetSignal("Alphasig");
16945 Float_t fAlphabkg=fBurstParameters->GetSignal("Alphabkg");
16946 Float_t fAvgrbz=fBurstParameters->GetSignal("Avgrbz");
16947 Float_t fAvgrbt90=fBurstParameters->GetSignal("Avgrbt90");
16948 Int_t fTunits=TMath::Nint(fBurstParameters->GetSignal("Tunits"));
16949
16950 TString tu="days";
16951 if (fTunits==1) tu="hours";
16952 if (fTunits==2) tu="sec";
16953 if (fTunits==3) tu="ns";
16954 if (fTunits==4) tu="ps";
16955
16956 TString title;
16957 TString s;
16958
16959 // Initialize the On-source and Off-source data samples
16960 fBurstOnReco.Reset();
16961 fBurstOnMatch.Reset();
16962 fBurstSigReco.Reset();
16963 fBurstSignal.Reset();
16964 fBurstOffReco.Reset();
16965 fBurstOffMatch.Reset();
16966 fBurstOnReco.SetNameTitle("BurstOnReco","On-source reco data");
16967 fBurstOnReco.SetStoreMode();
16968 fBurstOnReco.SetNames("zburst","sigmaburst","sigmareco","sigmacomb");
16969 fBurstOnMatch.SetNameTitle("BurstOnMatch","On-source matching data");
16970 fBurstOnMatch.SetStoreMode();
16971 fBurstOnMatch.SetNames("E","dtime","dang","dtimez");
16972 fBurstSigReco.SetNameTitle("BurstSigReco","Recorded simulated signal reco data");
16973 fBurstSigReco.SetStoreMode();
16974 fBurstSigReco.SetNames("zburst","sigmaburst","sigmareco","sigmacomb");
16975 fBurstSignal.SetNameTitle("BurstSignal","Recorded simulated signal events");
16976 fBurstSignal.SetStoreMode();
16977 fBurstSignal.SetNames("E","dtime","dang","dtimez");
16978 fBurstOffReco.SetNameTitle("BurstOffReco","Off-source reco data");
16979 fBurstOffReco.SetStoreMode();
16980 fBurstOffReco.SetNames("zburst","sigmaburst","sigmareco","sigmacomb");
16981 fBurstOffMatch.SetNameTitle("BurstOffMatch","Off-source matching data");
16982 fBurstOffMatch.SetStoreMode();
16983 fBurstOffMatch.SetNames("E","dtime","dang","dtimez");
16984 fBurstOnAeff.Reset();
16985 fBurstOffAeff.Reset();
16986 fBurstSigAeff.Reset();
16987 fBurstOnAeff.SetNameTitle("BurstOnAeff","On-source track Aeff, Fluence, E and dang data");
16988 fBurstOnAeff.SetStoreMode();
16989 fBurstOnAeff.SetNames("Aeff","Fluence","E","dang");
16990 fBurstOffAeff.SetNameTitle("BurstOffAeff","Off-source track Aeff, Fluence, E and dang data");
16991 fBurstOffAeff.SetStoreMode();
16992 fBurstOffAeff.SetNames("Aeff","Fluence","E","dang");
16993 fBurstSigAeff.SetNameTitle("BurstSigAeff","Recorded simulated signal track Aeff, Fluence, E and dang data");
16994 fBurstSigAeff.SetStoreMode();
16995 fBurstSigAeff.SetNames("Aeff","Fluence","E","dang");
16996
16997 // Set default simulation signal and background energy spectra if needed
16998 if (!mode)
16999 {
17000 TH1* edist=0;
17001 edist=(TH1*)fBurstHistos.FindObject("hSigEprofile");
17002 if (!edist) MakeBurstEnergydist("SigE",fAlphasig,10000);
17003 edist=(TH1*)fBurstHistos.FindObject("hBkgEprofile");
17004 if (!edist) MakeBurstEnergydist("BkgE",fAlphabkg,10000);
17005 }
17006
17008 // Some statistics from the loaded data //
17010
17011 Int_t fNgrbs=GetNsignals(0);
17012 Int_t fNevts=GetNsignals(1);
17013
17014 Float_t xmin=0;
17015 Float_t xmax=0;
17016 Float_t range=0;
17017 Int_t nbins=100;
17018 Float_t binsize=0;
17019 Int_t srcbufsize=10000;
17020 if (fNgrbs && fNgrbs<srcbufsize) srcbufsize=fNgrbs;
17021 Int_t evtbufsize=10000;
17022 if (fNevts && fNevts<evtbufsize) evtbufsize=fNevts;
17023
17024 // Creation of the burst redshift histo
17025 title.Form("Redshifts for the selected source sample;Redshift;Counts");
17026 TH1F* hSourceZ=new TH1F("hSourceZ",title,nbins,1,0);
17027 hSourceZ->SetBuffer(srcbufsize);
17028
17029 // Creation of the corresponding physical distance histo
17030 nbins=100;
17031 title.Form("Distances for the selected source sample derived from the redshifts;Physical distance in Mpc;Counts");
17032 TH1F* hSourceD=new TH1F("hSourceD",title,nbins,xmin,xmax);
17033 hSourceD->SetBuffer(srcbufsize);
17034
17035 // Creation of the burst t90 duration histo
17036 xmin=-5;
17037 if (fabs(fT90min)>0) xmin=log10(fabs(fT90min));
17038 xmax=5;
17039 if (fT90max>0) xmax=log10(fT90max);
17040 range=xmax-xmin;
17041 binsize=0.2; // Bins of 0.2
17042 nbins=TMath::Nint(range/binsize);
17043 if (nbins<1)
17044 {
17045 xmin=xmin-1.;
17046 xmax=xmax+1.;
17047 nbins=10;
17048 }
17049 title.Form("Burst durations for the selected source sample;Burst duration ^{10}log(T90) in sec.;Counts");
17050 TH1F* hBurstT90=new TH1F("hBurstT90",title,nbins,xmin,xmax);
17051
17052 // Creation of the full selected sample burst position uncertainty histo with automatic binning
17053 nbins=100;
17054 title.Form("Position uncertainties for the selected source sample;Position angular uncertainty (sigma in degrees);Counts");
17055 TH1F* hSigmaSource=new TH1F("hSigmaSource",title,nbins,1,0);
17056 hSigmaSource->SetBuffer(srcbufsize);
17057
17058 // Creation of the real event reconstructed energy histo with automatic binning
17059 TH1F* hEreco=0;
17060 nbins=1000;
17061 if (mode==1)
17062 {
17063 title.Form("Reconstructed energy for the full selected real event sample;Reconstructed event energy in GeV;Counts");
17064 hEreco=new TH1F("hEreco",title,nbins,1,0);
17065 hEreco->SetBuffer(evtbufsize);
17066 }
17067
17068 // Creation of the injected source signal event energy histo with automatic binning
17069 TH1F* hSigE=0;
17070 TH1F* hSigEzcor=0;
17071 nbins=1000;
17072 if (mode==0)
17073 {
17074 title.Form("Injected signal energy at the source;Event energy in GeV;Counts");
17075 hSigE=new TH1F("hSigE",title,nbins,1,0);
17076 fBurstHistos.Add(hSigE);
17077 title.Form("(Redshift corrected) injected signal energy arriving at Earth;Event energy in GeV;Counts");
17078 hSigEzcor=new TH1F("hSigEzcor",title,nbins,1,0);
17079 fBurstHistos.Add(hSigEzcor);
17080 }
17081
17082 // Creation of the full selected sample event reconstruction uncertainty histo with automatic binning
17083 TH1F* hSigmaReco=0;
17084 nbins=100;
17085 title.Form("Event reconstruction uncertainties for the full selected sample;Event angular reconstruction uncertainty (sigma in degrees);Counts");
17086 hSigmaReco=new TH1F("hSigmaReco",title,nbins,1,0);
17087 hSigmaReco->SetBuffer(evtbufsize);
17088
17089 // Fill the generic source c.q. burst histograms
17090 NcSignal* sx=0;
17091 Float_t zgrb=0;
17092 Double_t dgrb=0;
17093 Float_t t90grb=0;
17094 Float_t sigmagrb=0;
17095 NcSample zsample;
17096 zsample.SetStoreMode();
17097 NcSample t90sample;
17098 t90sample.SetStoreMode();
17099 NcSample sigmasample;
17100 sigmasample.SetStoreMode();
17101 Int_t nsig=GetNsignals(0,1);
17102 for (Int_t i=1; i<=nsig; i++)
17103 {
17104 sx=GetSignal(i,0);
17105
17106 if (!sx) continue;
17107
17108 zgrb=sx->GetSignal("z");
17109 dgrb=GetPhysicalDistance(zgrb);
17110 t90grb=sx->GetSignal("T90");
17111 sigmagrb=sx->GetSignal("csigma");
17112
17113 hSourceZ->Fill(zgrb);
17114 hSourceD->Fill(dgrb);
17115 if (t90grb>0) hBurstT90->Fill(log10(t90grb));
17116 hSigmaSource->Fill(sigmagrb);
17117
17118 if (fAvgrbz<0) zsample.Enter(zgrb);
17119 if (fAvgrbt90<0) t90sample.Enter(t90grb);
17120 sigmasample.Enter(sigmagrb);
17121 }
17122
17123 // Add the filled histograms to the storage container
17124 if (hSourceZ->GetEntries()) fBurstHistos.Add(hSourceZ);
17125 if (hSourceD->GetEntries()) fBurstHistos.Add(hSourceD);
17126 if (hBurstT90->GetEntries()) fBurstHistos.Add(hBurstT90);
17127 if (hSigmaSource->GetEntries()) fBurstHistos.Add(hSigmaSource);
17128
17129 // Determine median redshift if requested
17130 if (fAvgrbz<0)
17131 {
17132 fAvgrbz=zsample.GetMedian(1);
17133 fAvgrbz*=-1.;
17134 }
17135
17136 // Determine median T90 duration if requested
17137 if (fAvgrbt90<0)
17138 {
17139 fAvgrbt90=t90sample.GetMedian(1);
17140 fAvgrbt90*=-1.;
17141 }
17142
17143 Float_t fAvgrbsigma=sigmasample.GetMedian(1);
17144
17145 // Fill the generic event histograms
17146 Float_t sigmareco=0;
17147 Float_t Ereco=0;
17148 nsig=GetNsignals(1,1);
17149 for (Int_t i=1; i<=nsig; i++)
17150 {
17151 sx=GetSignal(i,1);
17152
17153 if (!sx) continue;
17154
17155 sigmareco=sx->GetSignal("csigma");
17156 Ereco=sx->GetSignal("E");
17157
17158 if (hSigmaReco) hSigmaReco->Fill(sigmareco);
17159 if (hEreco) hEreco->Fill(Ereco);
17160 }
17161
17162 // Add the filled histograms to the storage container
17163 if (hSigmaReco->GetEntries()) fBurstHistos.Add(hSigmaReco);
17164 if (hEreco)
17165 {
17166 if (hEreco->GetEntries()) fBurstHistos.Add(hEreco);
17167 }
17168
17169 // Update internal statistics
17170 fBurstParameters->SetSignal(fAvgrbz,"Avgrbz");
17171 fBurstParameters->SetSignal(fAvgrbt90,"Avgrbt90");
17172 fBurstParameters->AddNamedSlot("Avgrbsigma");
17173 fBurstParameters->SetSignal(fAvgrbsigma,"Avgrbsigma");
17174}
17175
17177{
17183
17184 // Retreive the needed parameters
17185 Float_t fGrbnu=fBurstParameters->GetSignal("Grbnu");
17186 Int_t fNgrbs=TMath::Nint(fBurstParameters->GetSignal("Ngrbs"));
17187 Int_t fInburst=TMath::Nint(fBurstParameters->GetSignal("Inburst"));
17188 Float_t fDtnu=fBurstParameters->GetSignal("Dtnu");
17189 Float_t fDtnus=fBurstParameters->GetSignal("Dtnus");
17190 Float_t fTimres=fBurstParameters->GetSignal("Timres");
17191 Int_t fDatype=TMath::Nint(fBurstParameters->GetSignal("Datype"));
17192 Float_t fDawin=fBurstParameters->GetSignal("Dawin");
17193 Float_t fTfact=fBurstParameters->GetSignal("Tfact");
17194 Int_t fEzcor=TMath::Nint(fBurstParameters->GetSignal("Ezcor"));
17195 Int_t fPDFsigE=TMath::Nint(fBurstParameters->GetSignal("PDFsigE"));
17196 Float_t fEmin=fBurstParameters->GetSignal("Emin");
17197 Float_t fEmax=fBurstParameters->GetSignal("Emax");
17198 Int_t fKinangle=TMath::Nint(fBurstParameters->GetSignal("Kinangle"));
17199 Float_t fAngresmin=fBurstParameters->GetSignal("Angresmin");
17200 Float_t fAngresmax=fBurstParameters->GetSignal("Angresmax");
17201 Float_t fAngresfix=fBurstParameters->GetSignal("Angresfix");
17202 Int_t fSumsigmas=TMath::Nint(fBurstParameters->GetSignal("Sumsigmas"));
17203 Float_t fTmin=fBurstParameters->GetSignal("Tmin");
17204 Float_t fTmax=fBurstParameters->GetSignal("Tmax");
17205
17206 // Deactivate redshift correction for source signal events from archival observed data
17207 if (!fPDFsigE)
17208 {
17209 fEzcor=0;
17210 fBurstParameters->SetSignal(0,"Ezcor");
17211 }
17212
17213 Int_t nmu=int(fabs(fGrbnu)*float(fNgrbs));
17214 Int_t jgrb=0;
17215 NcSignal* sx=0;
17216 NcTimestamp* tx=0;
17217 Float_t t90grb=0;
17218 Float_t zgrb=0;
17219 Float_t sigmagrb=0;
17220 NcPosition rgrb;
17221 NcPosition rgrb2;
17222 Float_t dt=0;
17223 Double_t dgrb=0;
17224 Double_t thetagrb=0;
17225 Double_t phigrb=0;
17226 Float_t dang=0;
17227 Float_t dangmax=0;
17228 Float_t dangmaxOn=0;
17229 NcPosition rmu;
17230 Double_t E=0;
17231 Double_t sigmareco=0;
17232 Float_t sigmatot=0;
17233 Float_t OmegaOn=0; // The current on-source solid angle probed for a certain GRB
17234 Float_t thlow=0;
17235 Float_t thup=0;
17236 Float_t solidangle=0;
17237 Int_t fixedwinset=0; // Flag to indicate whether a fixed angular search window was set (1) or not (0) for this burst
17238
17239 TH1* hSigE=(TH1*)fBurstHistos.FindObject("hSigE");
17240 TH1* hSigEzcor=(TH1*)fBurstHistos.FindObject("hSigEzcor");
17241 TH2* hAeffProfile=(TH2*)fBurstHistos.FindObject("hAeffProfile");
17242
17243 // The bin numbers and Aeff value in the AeffProfile for the (E,theta) of the track
17244 Int_t nbins=0;
17245 if (hAeffProfile) nbins=(hAeffProfile->GetNbinsX())*(hAeffProfile->GetNbinsY());
17246 Int_t gbin=0; // The global bin number in the histogram
17247 Double_t Aeff=0;
17248 Double_t Fluence=0;
17249 Double_t thetamu=0;
17250
17251 while (nmugrb<nmu)
17252 {
17253 // Pick randomly one of the stored GRBs
17254 jgrb=int(fRan->Uniform(0.,float(fNgrbs)));
17255 if (jgrb==0) jgrb=1;
17256 sx=GetSignal(jgrb);
17257
17258 if (!sx) continue;
17259
17260 tx=sx->GetTimestamp();
17261 GetSignal(dgrb,thetagrb,"deg",phigrb,"deg","loc",tx,jgrb);
17262 rgrb.SetPosition(1,thetagrb,phigrb,"sph","deg");
17263 zgrb=sx->GetSignal("z");
17264 t90grb=sx->GetSignal("T90");
17265 sigmagrb=sx->GetSignal("csigma");
17266 fixedwinset=TMath::Nint(sx->GetSignal("fixedwinset"));
17267 dangmaxOn=sx->GetSignal("dangmaxOn");
17268 OmegaOn=sx->GetSignal("OmegaOn");
17269
17270 dangmax=dangmaxOn;
17271
17272 // Obtain real GRB position
17273 rgrb2.Load(rgrb);
17274 SmearPosition(rgrb2,sigmagrb);
17275
17276 nmugrb++;
17277
17278 if (!fInburst) // Neutrino and gamma production decoupled
17279 {
17280 if (fDtnus<0) // Sigma in units of T90
17281 {
17282 dt=fRan->Gauss(fDtnu,fabs(fDtnus)*t90grb);
17283 }
17284 else // Sigma in seconds
17285 {
17286 dt=fRan->Gauss(fDtnu,fDtnus);
17287 }
17288 dt=dt*(zgrb+1.);
17289 }
17290 else // Coupled neutrino and gamma production
17291 {
17292 if (fDtnus<0) // Sigma in units of T90
17293 {
17294 dt=fRan->Gauss(fDtnu*t90grb,fabs(fDtnus)*t90grb);
17295 }
17296 else // Sigma in seconds
17297 {
17298 dt=fRan->Gauss(fDtnu*t90grb,fDtnus);
17299 }
17300 }
17301 if (fTimres>0) dt=fRan->Gauss(dt,fTimres);
17302
17303 // Convert dt from seconds to the selected Tunits
17304 dt=dt/fTfact;
17305
17306 // The direction of the GRB signal
17307 rmu.Load(rgrb2);
17308
17309 // The energy of the GRB signal
17311
17312 if (hSigE) hSigE->Fill(E);
17313
17314 // Reduce the energy due to the cosmological redshift effect
17315 if (fEzcor) E=E/(zgrb+1.);
17316
17317 if (hSigEzcor) hSigEzcor->Fill(E);
17318
17319 if (E<0 || E<fEmin || E>fEmax) continue;
17320
17321 // Modification to account for the neutrino-lepton kinematic opening angle
17322 if (fKinangle>0)
17323 {
17324 Int_t mode=fKinangle-1;
17325 Double_t ang=GetNeutrinoAngle(E,"deg",mode);
17326 if (ang>0) ShiftPosition(rmu,ang);
17327 }
17328
17329 // Smearing according to the reconstruction angular resolution
17330 sigmareco=GetBurstRecoAngres(E,E);
17331 if (sigmareco<0) sigmareco=fAngresfix;
17332
17333 if (sigmareco<fAngresmin || sigmareco>fAngresmax) continue;
17334
17335 SmearPosition(rmu,sigmareco);
17336
17337 // Determine angular difference w.r.t. the presumed GRB position
17338 dang=rgrb.GetOpeningAngle(rmu,"deg");
17339
17340 sigmatot=-1;
17341 if (fSumsigmas==-1) sigmatot=sigmareco;
17342 if (fSumsigmas==0) sigmatot=sigmagrb;
17343 if (fSumsigmas==1) sigmatot=sigmagrb+sigmareco;
17344 if (fSumsigmas==2) sigmatot=sqrt(sigmagrb*sigmagrb+sigmareco*sigmareco);
17345
17346 // Determine the dynamic angular window including the track reco uncertainty
17347 if (!fixedwinset)
17348 {
17349 dangmax=-1;
17350 if (sigmatot>=0) dangmax=fabs(fDawin*sigmatot);
17351 }
17352
17353 if (fDatype>=0 && dang>dangmax) continue;
17354
17355 if (dt<fTmin || dt>fTmax) continue;
17356
17357 fBurstOnReco.Enter(zgrb,sigmagrb,sigmareco,sigmatot);
17358 fBurstOnMatch.Enter(E,dt,dang,dt/(zgrb+1.));
17359 fBurstSigReco.Enter(zgrb,sigmagrb,sigmareco,sigmatot);
17360 fBurstSignal.Enter(E,dt,dang,dt/(zgrb+1.));
17361 fBurstParameters->AddSignal(E,"EnergyOn");
17362 fBurstParameters->AddSignal(E,"EnergySig");
17363 if (hAeffProfile)
17364 {
17365 thetamu=rmu.GetX(2,"sph","rad");
17366 gbin=hAeffProfile->FindFixBin(log10(E),cos(thetamu));
17367 if (gbin>0 && gbin<nbins+1)
17368 {
17369 Aeff=hAeffProfile->GetBinContent(gbin);
17370 if (Aeff>0)
17371 {
17372 Fluence=1./Aeff;
17373 fBurstOnAeff.Enter(Aeff,Fluence,E,dang);
17374 fBurstSigAeff.Enter(Aeff,Fluence,E,dang);
17375 }
17376 }
17377 }
17378
17379 if (fixedwinset) continue;
17380
17381 // Update the dynamic On-source maximum (solid) angle that is encountered for this burst
17382 if (fDawin<0) // Local zenith band centered at the GRB position at its trigger time
17383 {
17384 thlow=thetagrb-0.5*dangmax;
17385 thup=thetagrb+0.5*dangmax;
17386 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
17387 }
17388 else // Circle around GRB position
17389 {
17390 thlow=0;
17391 thup=dangmax;
17392 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
17393 }
17394 if (dangmax>dangmaxOn) sx->SetSignal(dangmax,"dangmaxOn");
17395 if (solidangle>OmegaOn) sx->SetSignal(solidangle,"OmegaOn");
17396 }
17397}
17398
17399TH1* NcAstrolab::GetBurstBayesianSignalRate(Double_t p,Double_t& rlow,Double_t& rup,Int_t n)
17400{
17431
17432 rlow=0;
17433 rup=0;
17434
17435 // The number of on-source and off-source patches
17436 Int_t fNgrbs=GetNsignals(0);
17437 Int_t fNbkg=TMath::Nint(fBurstParameters->GetSignal("Nbkg"));
17438
17439 // The recorded (stacked) on-source and off-source number of events
17440 Double_t Non=fBurstOnMatch.GetN();
17441 Double_t Noff=fBurstOffMatch.GetN();
17442
17443 if (fNgrbs<=0 || fNbkg<=0 || Non<=0 || Noff<=0)
17444 {
17445 printf(" \n *%-s::GetBurstBayesianSignalRate* \n",ClassName());
17446 if (fNgrbs<=0 || Non<=0) printf(" === No on-source data available === \n");
17447 if (fNbkg<=0 || Noff<=0) printf(" === No off-source data available === \n");
17448 return 0;
17449 }
17450
17451 Int_t fTunits=TMath::Nint(fBurstParameters->GetSignal("Tunits"));
17452 Float_t fTfact=fBurstParameters->GetSignal("Tfact");
17453
17454 TString tu="days";
17455 if (fTunits==1) tu="hours";
17456 if (fTunits==2) tu="sec";
17457 if (fTunits==3) tu="ns";
17458 if (fTunits==4) tu="ps";
17459
17460 // Solid angle of the selected RA and DEC range
17461 Float_t fOmegaDecl=fBurstParameters->GetSignal("OmegaDecl");
17462
17463 // The (stacked) on-source and off-source solid angles that were probed
17464 Double_t fSolidangleOn=fBurstParameters->GetSignal("SolidangleOn");
17465 Double_t fSolidangleOff=fBurstParameters->GetSignal("SolidangleOff");
17466 Double_t fAvSolidangleOn=fBurstParameters->GetSignal("AvSolidangleOn");
17467 Double_t fAvSolidangleOff=fBurstParameters->GetSignal("AvSolidangleOff");
17468 Double_t Ra=-1;
17469 if (fAvSolidangleOff) Ra=fAvSolidangleOn/fAvSolidangleOff;
17470
17471 // The integrated on-source and off-source exposure times in seconds
17472 Double_t Ton=fBurstParameters->GetSignal("TtotOn");
17473 Double_t Toff=fBurstParameters->GetSignal("TtotOff");
17474
17475 // The Bayesian posterior background and signal rate PDFs
17476 TF1 fbkgrpdf=GetBackgroundRatePDF(Noff,Toff);
17477 TF1 fsigrpdf=GetSignalRatePDF(Non,Ton,Noff,Toff,Ra);
17478
17479 Double_t rmode=fsigrpdf.GetMaximumX();
17480 Double_t bkgrmode=fbkgrpdf.GetMaximumX();
17481
17482 // Determine the "p%" credible interval for the signal rate
17483 Float_t frac=0;
17484 frac=GetCredibleInterval(fsigrpdf,p,rlow,rup,n);
17485
17486 // Provide the signal and background rate PDFs as histograms in the output file
17487 fbkgrpdf.SetRange(0,3.*Noff/Toff);
17488 fbkgrpdf.SetNpx(n);
17489 TH1* hBkgRatePDF=(TH1*)fbkgrpdf.GetHistogram()->Clone();
17490 hBkgRatePDF->SetName("hBkgRatePDF");
17491 fBurstHistos.Add(hBkgRatePDF);
17492 fsigrpdf.SetRange(0,3.*Non/Ton);
17493 fsigrpdf.SetNpx(n);
17494 TH1* hSigRatePDF=(TH1*)fsigrpdf.GetHistogram()->Clone();
17495 hSigRatePDF->SetName("hSigRatePDF");
17496 fBurstHistos.Add(hSigRatePDF);
17497
17498 printf("\n *%-s::GetBurstBayesianSignalRate* Credible interval [rlow,rup] for p=%-g%% with a precision of 1/%-i \n",ClassName(),p,n);
17499
17500 // Issue a warning in case variable angular cones based on actual track reco sigmas were used.
17501 // This can induce large variations in the on-source and off-source event counts
17502 Int_t fDatype=TMath::Nint(fBurstParameters->GetSignal("Datype"));
17503 Int_t fRecoangle=TMath::Nint(fBurstParameters->GetSignal("Recoangle"));
17504 Int_t fSumsigmas=TMath::Nint(fBurstParameters->GetSignal("Sumsigmas"));
17505
17506 if (fRecoangle && fSumsigmas && fDatype==2)
17507 {
17508 printf(" === Warning: Variable angular cones based on actual track reconstruction sigmas were used. \n");
17509 printf(" Large variations between the on-source and off-source background counts may be present. \n");
17510 }
17511
17512 printf(" The %-g%% credible interval from the Bayesian posterior signal pdf : [%-g,%-g] Hz \n",100.*frac,rlow,rup);
17513 printf(" Modes of the on-source posterior PDFs : Signal=%-g Hz Background=%-g Hz",rmode,bkgrmode);
17514 if (bkgrmode) printf(" Signal/Background=%-g",rmode/bkgrmode);
17515 printf("\n");
17516 printf(" The following signal and background rate PDF histograms have been generated : \n");
17517 printf(" ... %-s : %-s \n",hSigRatePDF->GetName(),hSigRatePDF->GetTitle());
17518 printf(" ... %-s : %-s \n",hBkgRatePDF->GetName(),hBkgRatePDF->GetTitle());
17519
17520 // The area covered c.q. overlooked by the detector sensors
17521 Float_t fSensarea=fBurstParameters->GetSignal("Sensarea");
17522 fSensarea*=1e4; // Convert to cm^2
17523
17524 printf(" Solid angle coverage corresponding to the selected RA and DEC range : %-g steradian \n",fOmegaDecl);
17525 printf(" Integrated on-source exposure time of the %-i stacked time windows : %-g %-s \n",fNgrbs,Ton/fTfact,tu.Data());
17526 printf(" Integrated off-source exposure time of the %-i*%-i stacked time windows : %-g %-s \n",fNgrbs,fNbkg,Toff/fTfact,tu.Data());
17527 printf(" Total accumulated on-source solid angle : %-g sr in %-i stacked patches --> Average per patch : %-g sr \n",fSolidangleOn,fNgrbs,fAvSolidangleOn);
17528 printf(" Total accumulated off-source solid angle : %-g sr in %-i*%-i stacked patches --> Average per patch : %-g sr \n",fSolidangleOff,fNgrbs,fNbkg,fAvSolidangleOff);
17529 if (fSensarea>0) printf(" Area covered c.q. overlooked by the detector sensors : %-g cm^2. \n",fSensarea);
17530
17531 printf(" Total number of recorded on-source events : %-g --> Average per patch : %-g events. \n",Non,Non/float(fNgrbs));
17532 printf(" Total number of recorded off-source events : %-g --> Average per patch : %-g events. \n",Noff,Noff/float(fNgrbs*fNbkg));
17533
17534 // Provide statistics for the signal rate PDF mode, lower and upper boundaries as well as the mode of the background PDF
17535 for (Int_t i=1; i<3; i++)
17536 {
17537 printf(" ********************************************************************** \n");
17538 if (i==1)
17539 {
17540 printf(" * Accumulated (stacked) on-source values based on the posterior PDFs * \n");
17541 }
17542 else
17543 {
17544 printf(" * Average values per on-source patch based on the posterior PDFs * \n");
17545 }
17546 printf(" ********************************************************************** \n");
17547
17548 TString text;
17549
17550 printf(" *Lower bound* Steady signal event rate during each time window : %-g Hz",rlow);
17551 if (fAvSolidangleOn) printf(" --> %-g Hz sr^-1",rlow/fAvSolidangleOn);
17552 printf("\n");
17553 text.Form("CL%-iLower",TMath::Nint(p));
17554 ListBurstSignalStats(rlow,i,text);
17555
17556 printf(" *Mode* Steady signal event rate during each time window : %-g Hz",rmode);
17557 if (fAvSolidangleOn) printf(" --> %-g Hz sr^-1",rmode/fAvSolidangleOn);
17558 printf("\n");
17559 ListBurstSignalStats(rmode,i,"Mode");
17560
17561 printf(" *Upper bound* Steady signal event rate during each time window : %-g Hz",rup);
17562 if (fAvSolidangleOn) printf(" --> %-g Hz sr^-1",rup/fAvSolidangleOn);
17563 printf("\n");
17564 text.Form("CL%-iUpper",TMath::Nint(p));
17565 ListBurstSignalStats(rup,i,text);
17566
17567 printf(" *Background* Steady background event rate during each time window : %-g Hz",bkgrmode);
17568 if (fAvSolidangleOn) printf(" --> %-g Hz sr^-1",bkgrmode/fAvSolidangleOn);
17569 printf("\n");
17570
17571 ListBurstSignalStats(bkgrmode,-i);
17572 }
17573 return hSigRatePDF;
17574}
17575
17576Double_t NcAstrolab::GetBurstTotalFluence(Double_t nsig,TString str)
17577{
17593
17594 Double_t Ton=fBurstParameters->GetSignal("TtotOn");
17595
17596 Double_t Fluence=-1;
17597
17598 Int_t n=TMath::Nint(nsig);
17599
17600 if (n<1 || Ton<=0) return -1;
17601
17602 Int_t nen=fBurstOnAeff.GetN();
17603
17604 if (n>nen) n=nen; // Only stored values should be used
17605
17606 // Take the Fluence sum of the "nsig" values ordered by increasing angular separation.
17607 // The assumption is that the closest tracks represent signal tracks.
17608 // Also an incoming Fluence vs. E histogram will be created for each "signal track".
17609 Double_t E=0;
17610 Double_t Stot=0;
17611 TString nameS,titleS,nameF,titleF,nameE2F,titleE2F;
17612 nameS.Form("h%-sFluence",str.Data());
17613 titleS.Form("Stacked incoming signal Fluence for Bayesian %s rate;Event energy [GeV];dN/(dEdA) [GeV^{-1} cm^{-2}]",str.Data());
17614 nameF.Form("h%-sFlux",str.Data());
17615 titleF.Form("Incoming signal Flux for a steady Bayesian %s rate;Event energy [GeV];dN/(dEdAdt) [GeV^{-1} cm^{-2} s^{-1}]",str.Data());
17616 nameE2F.Form("h%-sE2Flux",str.Data());
17617 titleE2F.Form("E-Scaled incoming signal Flux for a steady Bayesian %s rate;Event energy [GeV];E^{2}dN/(dEdAdt) [GeV cm^{-2} s^{-1}]",str.Data());
17618 TH1F* hS=0;
17619 TH1F* hF=0;
17620 TH1F* hE2F=0;
17621
17622 if (str!="-")
17623 {
17624 hS=(TH1F*)fBurstHistos.FindObject(nameS);
17625 hF=(TH1F*)fBurstHistos.FindObject(nameF);
17626 hE2F=(TH1F*)fBurstHistos.FindObject(nameE2F);
17627 if (hS)
17628 {
17629 delete hS;
17630 hS=new TH1F(nameS,titleS,100,0,-1);
17631 delete hF;
17632 hF=new TH1F(nameF,titleF,100,0,-1);
17633 delete hE2F;
17634 hE2F=new TH1F(nameE2F,titleE2F,100,0,-1);
17635 }
17636 else
17637 {
17638 hS=new TH1F(nameS,titleS,100,0,-1);
17639 fBurstHistos.Add(hS);
17640 hF=new TH1F(nameF,titleF,100,0,-1);
17641 fBurstHistos.Add(hF);
17642 hE2F=new TH1F(nameE2F,titleE2F,100,0,-1);
17643 fBurstHistos.Add(hE2F);
17644 }
17645
17646 hS->Sumw2();
17647 hF->Sumw2();
17648 hE2F->Sumw2();
17649 }
17650
17651 for (Int_t i=1; i<=n; i++)
17652 {
17653 Fluence=fBurstOnAeff.GetEntry(i,"Fluence",1,"dang");
17654 E=fBurstOnAeff.GetEntry(i,"E",1,"dang");
17655 Stot+=Fluence;
17656 if (Fluence>0 && hS)
17657 {
17658 hS->Fill(E,Fluence);
17659 hF->Fill(E,Fluence/Ton);
17660 hE2F->Fill(E,pow(E,2)*Fluence/Ton);
17661 }
17662 }
17663
17664 // Convert the histogram data into dN/dE
17665 if (hS)
17666 {
17667 // Flush the storage buffers to actually fill the histograms
17668 hS->BufferEmpty(1);
17669 hF->BufferEmpty(1);
17670 hE2F->BufferEmpty(1);
17671 Float_t binwidth=hS->GetBinWidth(1);
17672 if (binwidth>0)
17673 {
17674 hS->Scale(1./binwidth);
17675 hF->Scale(1./binwidth);
17676 hE2F->Scale(1./binwidth);
17677 }
17678 }
17679
17680 return Stot;
17681}
17682
17683void NcAstrolab::ListBurstSignalStats(Double_t Rate,Int_t mode,TString str)
17684{
17703
17704 // The number of on-source patches
17705 Int_t fNgrbs=GetNsignals(0);
17706
17707 // The integrated on-source exposure time in seconds
17708 Float_t Ton=fBurstParameters->GetSignal("TtotOn");
17709 Float_t TwinOn=Ton/float(fNgrbs); // The average time window in seconds
17710
17711 // The (stacked) on-source solid angle that was probed
17712 Float_t fSolidangleOn=fBurstParameters->GetSignal("SolidangleOn");
17713 Float_t fAvSolidangleOn=fBurstParameters->GetSignal("AvSolidangleOn");
17714
17715 // The area covered c.q. overlooked by the detector sensors
17716 Float_t fSensarea=fBurstParameters->GetSignal("Sensarea");
17717 fSensarea*=1e4; // Convert to cm^2
17718
17719 // The total accumulated on-source values
17720 Float_t Time=Ton;
17721 Float_t Omega=fSolidangleOn;
17722
17723 // Use the (averaged) observation values per patch
17724 if (abs(mode)==2)
17725 {
17726 Time=TwinOn;
17727 Omega=fAvSolidangleOn;
17728 }
17729
17730 // Determine the corresponding expected number of events
17731 Float_t Nevt=Rate*Time;
17732
17733 Float_t Fluence=-1;
17734 if (mode==1)
17735 {
17736 Fluence=GetBurstTotalFluence(Nevt,str);
17737 }
17738 if (mode==2)
17739 {
17740 Fluence=GetBurstTotalFluence(Nevt*float(fNgrbs),"-");
17741 Fluence=Fluence/float(fNgrbs);
17742 }
17743
17744 TString type="signal";
17745 if (mode<0) type="background";
17746
17747 printf(" Expected recorded number of %-s events : %-g",type.Data(),Nevt);
17748 if (Omega) printf(" --> %-g events/sr",Nevt/Omega);
17749 printf("\n");
17750 if (fSensarea>0)
17751 {
17752 printf(" Expected recorded %-s particle fluence : %-g cm^-2",type.Data(),Nevt/fSensarea);
17753 if (Omega) printf(" --> %-g cm^-2 sr^-1",Nevt/(fSensarea*Omega));
17754 printf("\n");
17755 printf(" Expected recorded %-s particle flux : %-g cm^-2 s^-1",type.Data(),Rate/fSensarea);
17756 if (Omega) printf(" --> Intensity : %-g cm^-2 s^-1 sr^-1",Rate/(fSensarea*Omega));
17757 printf("\n");
17758 }
17759 if (Fluence>0)
17760 {
17761 printf(" Expected incoming %-s particle fluence : %-g cm^-2",type.Data(),Fluence);
17762 if (Omega) printf(" --> %-g cm^-2 sr^-1",Fluence/Omega);
17763 printf("\n");
17764 printf(" Expected incoming %-s particle flux : %-g cm^-2 s^-1",type.Data(),Fluence/Time);
17765 if (Omega) printf(" --> Intensity : %-g cm^-2 s^-1 sr^-1",Fluence/(Time*Omega));
17766 printf("\n");
17767 }
17768}
17769
17771{
17784
17785 Double_t sigma=0;
17786
17787 // The recorded (stacked) "on source" and "off source" number of events
17788 Double_t Non=fBurstOnMatch.GetN();
17789 Double_t Noff=fBurstOffMatch.GetN();
17790
17791 if (Non<=0 || Noff<=0)
17792 {
17793 printf(" \n *%-s::GetBurstLiMaSignificance* \n",ClassName());
17794 if (Non<=0) printf(" === No on source data available === \n");
17795 if (Noff<=0) printf(" === No off source data available === \n");
17796 return 0;
17797 }
17798
17799 // The (stacked) "on source" and "off source" solid angles that were probed
17800 Double_t fAvSolidangleOn=fBurstParameters->GetSignal("AvSolidangleOn");
17801 Double_t fAvSolidangleOff=fBurstParameters->GetSignal("AvSolidangleOff");
17802 Double_t Ra=-1;
17803 if (fAvSolidangleOff) Ra=fAvSolidangleOn/fAvSolidangleOff;
17804
17805 // The (stacked) "on source" and "off source" exposure times
17806 Double_t Ton=fBurstParameters->GetSignal("TtotOn");
17807 Double_t Toff=fBurstParameters->GetSignal("TtotOff");
17808
17809 NcMath m;
17810 sigma=m.LiMaSignificance(Non,Ton,Noff,Toff,Ra);
17811
17812 printf("\n *%-s::GetBurstLiMaSignificance* The Li-Ma signal significance is : %-g \n",ClassName(),sigma);
17813
17814 // Issue a warning in case variable angular cones based on actual track reco sigmas were used.
17815 // This can induce large variations in the on-source and off-source event counts
17816 Int_t fDatype=TMath::Nint(fBurstParameters->GetSignal("Datype"));
17817 Int_t fRecoangle=TMath::Nint(fBurstParameters->GetSignal("Recoangle"));
17818 Int_t fSumsigmas=TMath::Nint(fBurstParameters->GetSignal("Sumsigmas"));
17819
17820 if (fRecoangle && fSumsigmas && fDatype==2)
17821 {
17822 printf(" === Warning: Variable angular cones based on actual track reconstruction sigmas were used. \n");
17823 printf(" Large variations between the on-source and off-source background counts may be present. \n");
17824 }
17825
17826 return sigma;
17827}
17828
17829void NcAstrolab::GetBurstBayesianPsiStatistics(TString type,Double_t nr,Int_t ncut,Int_t ndt,Bool_t zcor,Int_t freq)
17830{
17911
17912 NcMath math;
17913
17914 TString text="none";
17915 if (type=="time") text="arrival time";
17916 if (type=="BBtime") text="stacked Bayesian Block event rate";
17917 if (type=="BBtimeN") text="per time window normalized Bayesian Block event rate";
17918 if (type=="BBrat") text="per time window normalized On-source/Off-source Bayesian Block event rate ratio";
17919 if (type=="angle") text="opening angle";
17920 if (type=="cosa") text="cos(opening angle)";
17921 if (type=="BBcosa") text="stacked Bayesian Block cos(opening angle)";
17922 if (type=="BBcosaN") text="per patch normalized Bayesian Block cos(opening angle)";
17923 if (type=="BBrac") text="per patch normalized On-source/Off-source Bayesian Block cos(opening angle) ratio";
17924 if (type=="dt") text="arrival time interval";
17925
17926 if (zcor)
17927 {
17928 text.ReplaceAll("arrival time","redshift corrected arrival time");
17929 text.ReplaceAll("event rate","redshift corrected event rate");
17930 }
17931
17932 if (text=="none")
17933 {
17934 printf("\n *%-s::GetBurstBayesianPsiStatistics* Unknown statistics type : %-s \n",ClassName(),type.Data());
17935 return;
17936 }
17937 else
17938 {
17939 printf("\n *%-s::GetBurstBayesianPsiStatistics* Analysis of %-s statistics \n",ClassName(),text.Data());
17940 }
17941
17942 Int_t fTunits=TMath::Nint(fBurstParameters->GetSignal("Tunits"));
17943 TString tu="days";
17944 if (fTunits==1) tu="hours";
17945 if (fTunits==2) tu="sec";
17946 if (fTunits==3) tu="ns";
17947 if (fTunits==4) tu="ps";
17948
17949 TH1* tot=0;
17950 TH1* bkg=0;
17951 TH1* rat=0;
17952
17953 Double_t psitot=-1, psibkg=-1, psirat=-1;
17954 Float_t psidif=0;
17955 Float_t psimintot=-1, psimaxtot=-1, psifractot=0;
17956 Float_t psiminbkg=-1, psimaxbkg=-1, psifracbkg=0;
17957 Float_t psiminrat=-1, psimaxrat=-1, psifracrat=0;
17958 Double_t nrxtot=-1, nrxbkg=-1, nrxrat=-1;
17959 Double_t pvaluetot=-1, pvaluebkg=-1, pvaluerat=-1;
17960
17961 TH1F* hPsiOn=0;
17962 TH1F* hPsiOff=0;
17963 TH1F* hPsiRat=0;
17964 TH1F* rtot=0;
17965 TH1F* rbkg=0;
17966 TH1F* rrat=0;
17967
17969 // Arrival time histo Bayesian statistics //
17971 if (type=="time")
17972 {
17973 if (!zcor) // Plain observed arrival times
17974 {
17975 tot=(TH1*)fBurstHistos.FindObject("hOnt");
17976 bkg=(TH1*)fBurstHistos.FindObject("hOfft");
17977 }
17978 else // Redshift corrected arrival times
17979 {
17980 tot=(TH1*)fBurstHistos.FindObject("hOnZt");
17981 bkg=(TH1*)fBurstHistos.FindObject("hOffZt");
17982 }
17983
17984 if (!tot) printf(" === No on source data available === \n");
17985 if (!bkg) printf(" === No off source data available === \n");
17986
17987 if (!tot && !bkg) return;
17988
17989 if (tot) psitot=math.PsiValue(tot,0,0,freq);
17990 if (bkg) psibkg=math.PsiValue(bkg,0,0,freq);
17991 psidif=psitot-psibkg;
17992
17993 // Extreme Psi values for a pure background hypothesis of the recorded arrival time entries
17994 if (tot)
17995 {
17996 psimintot=math.PsiExtreme(tot,0,0,-2);
17997 if (psitot<psimintot) psimintot=psitot;
17998 psimaxtot=math.PsiExtreme(tot,0,0,-1);
17999 if (psimaxtot>psimintot) psifractot=(psimaxtot-psitot)/(psimaxtot-psimintot);
18000 }
18001 if (bkg)
18002 {
18003 psiminbkg=math.PsiExtreme(bkg,0,0,-2);
18004 if (psibkg<psiminbkg) psiminbkg=psibkg;
18005 psimaxbkg=math.PsiExtreme(bkg,0,0,-1);
18006 if (psimaxbkg>psiminbkg) psifracbkg=(psimaxbkg-psibkg)/(psimaxbkg-psiminbkg);
18007 }
18008
18009 // P-value determination
18010 if (nr>=0)
18011 {
18012 if (!zcor) // Plain observed arrival times
18013 {
18014 hPsiOn=(TH1F*)fBurstHistos.FindObject("hPsiOnt");
18015 hPsiOff=(TH1F*)fBurstHistos.FindObject("hPsiOfft");
18016 }
18017 else // Redshift corrected arrival times
18018 {
18019 hPsiOn=(TH1F*)fBurstHistos.FindObject("hPsiOnZt");
18020 hPsiOff=(TH1F*)fBurstHistos.FindObject("hPsiOffZt");
18021 }
18022
18023 if (hPsiOn)
18024 {
18025 rtot=(TH1F*)hPsiOn->Clone();
18026 rtot->Reset();
18027 }
18028 else
18029 {
18030 if (tot)
18031 {
18032 if (!zcor) rtot=new TH1F("hPsiOnt","Psi distr. for bkg hypothesis of on-source arrival time data",100,psimintot-1.,psimaxtot+1.);
18033 if (zcor) rtot=new TH1F("hPsiOnZt","Psi distr. for bkg hypothesis of redshift corrected on-source arrival time data",100,psimintot-1.,psimaxtot+1.);
18034 }
18035 }
18036
18037 if (hPsiOff)
18038 {
18039 rbkg=(TH1F*)hPsiOff->Clone();
18040 rbkg->Reset();
18041 }
18042 else
18043 {
18044 if (bkg)
18045 {
18046 if (!zcor) rbkg=new TH1F("hPsiOfft","Psi distr. for bkg hypothesis of off-source arrival time data",100,psiminbkg-1.,psimaxbkg+1.);
18047 if (zcor) rbkg=new TH1F("hPsiOffZt","Psi distr. for bkg hypothesis of redshift corrected off-source arrival time data",100,psiminbkg-1.,psimaxbkg+1.);
18048 }
18049 }
18050
18051 if (tot)
18052 {
18053 pvaluetot=math.PsiPvalue(-1,nr,tot,0,0,freq,0,rtot,ncut,&nrxtot);
18054 fBurstHistos.Add(rtot);
18055 }
18056 if (bkg)
18057 {
18058 pvaluebkg=math.PsiPvalue(-1,nr,bkg,0,0,freq,0,rbkg,ncut,&nrxbkg);
18059 fBurstHistos.Add(rbkg);
18060 }
18061 }
18062 }
18063
18065 // Event rate histo Bayesian statistics //
18067 if (type.Contains("BBtime"))
18068 {
18069 if (!zcor) // Plain observed arrival times
18070 {
18071 if (!type.Contains("N"))
18072 {
18073 tot=(TH1*)fBurstHistos.FindObject("hOnBBt");
18074 bkg=(TH1*)fBurstHistos.FindObject("hOffBBt");
18075 }
18076 else
18077 {
18078 tot=(TH1*)fBurstHistos.FindObject("hOnBBtN");
18079 bkg=(TH1*)fBurstHistos.FindObject("hOffBBtN");
18080 }
18081 }
18082 else // Redshift corrected arrival times
18083 {
18084 if (!type.Contains("N"))
18085 {
18086 tot=(TH1*)fBurstHistos.FindObject("hOnBBzt");
18087 bkg=(TH1*)fBurstHistos.FindObject("hOffBBzt");
18088 }
18089 else
18090 {
18091 tot=(TH1*)fBurstHistos.FindObject("hOnBBztN");
18092 bkg=(TH1*)fBurstHistos.FindObject("hOffBBztN");
18093 }
18094 }
18095
18096 if (!tot) printf(" === No on source data available === \n");
18097 if (!bkg) printf(" === No off source data available === \n");
18098
18099 if (!tot && !bkg) return;
18100
18101 // Temporarily offset the bin contents so that the lowest bin content is 1 for the psi analysis
18102 if (tot)
18103 {
18104 for (Int_t i=1; i<=tot->GetNbinsX(); i++)
18105 {
18106 tot->AddBinContent(i,1);
18107 }
18108 }
18109
18110 if (bkg)
18111 {
18112 for (Int_t i=1; i<=bkg->GetNbinsX(); i++)
18113 {
18114 bkg->AddBinContent(i,1);
18115 }
18116 }
18117
18118 if (tot) psitot=math.PsiValue(tot,0,0,freq);
18119 if (bkg) psibkg=math.PsiValue(bkg,0,0,freq);
18120 psidif=psitot-psibkg;
18121
18122 // Extreme Psi values for a pure background hypothesis of the recorded arrival time entries
18123 if (tot)
18124 {
18125 psimintot=math.PsiExtreme(tot,0,0,-2);
18126 if (psitot<psimintot) psimintot=psitot;
18127 psimaxtot=math.PsiExtreme(tot,0,0,-1);
18128 if (psimaxtot>psimintot) psifractot=(psimaxtot-psitot)/(psimaxtot-psimintot);
18129 }
18130 if (bkg)
18131 {
18132 psiminbkg=math.PsiExtreme(bkg,0,0,-2);
18133 if (psibkg<psiminbkg) psiminbkg=psibkg;
18134 psimaxbkg=math.PsiExtreme(bkg,0,0,-1);
18135 if (psimaxbkg>psiminbkg) psifracbkg=(psimaxbkg-psibkg)/(psimaxbkg-psiminbkg);
18136 }
18137
18138 // P-value determination
18139 if (nr>=0)
18140 {
18141 if (!zcor) // Plain observed arrival times
18142 {
18143 hPsiOn=(TH1F*)fBurstHistos.FindObject("hPsiOnBBt");
18144 hPsiOff=(TH1F*)fBurstHistos.FindObject("hPsiOffBBt");
18145 if (type.Contains("N"))
18146 {
18147 hPsiOn=(TH1F*)fBurstHistos.FindObject("hPsiOnBBtN");
18148 hPsiOff=(TH1F*)fBurstHistos.FindObject("hPsiOffBBtN");
18149 }
18150 }
18151 else // Redshift corrected arrival times
18152 {
18153 hPsiOn=(TH1F*)fBurstHistos.FindObject("hPsiOnBBzt");
18154 hPsiOff=(TH1F*)fBurstHistos.FindObject("hPsiOffBBzt");
18155 if (type.Contains("N"))
18156 {
18157 hPsiOn=(TH1F*)fBurstHistos.FindObject("hPsiOnBBztN");
18158 hPsiOff=(TH1F*)fBurstHistos.FindObject("hPsiOffBBztN");
18159 }
18160 }
18161
18162 if (hPsiOn)
18163 {
18164 rtot=(TH1F*)hPsiOn->Clone();
18165 rtot->Reset();
18166 }
18167 else
18168 {
18169 if (tot)
18170 {
18171 if (!zcor)
18172 {
18173 if (type.Contains("N"))
18174 {
18175 rtot=new TH1F("hPsiOnBBtN","Psi distr. for bkg hypothesis of per time window normalized on-source event rate Bayesian Block data",100,psimintot-1.,psimaxtot+1.);
18176 }
18177 else
18178 {
18179 rtot=new TH1F("hPsiOnBBt","Psi distr. for bkg hypothesis of stacked on-source event rate Bayesian Block data",100,psimintot-1.,psimaxtot+1.);
18180 }
18181 }
18182 if (zcor)
18183 {
18184 if (type.Contains("N"))
18185 {
18186 rtot=new TH1F("hPsiOnBBztN","Psi distr. for bkg hypothesis of redshift corrected per time window normalized on-source event rate Bayesian Block data",100,psimintot-1.,psimaxtot+1.);
18187 }
18188 else
18189 {
18190 rtot=new TH1F("hPsiOnBBzt","Psi distr. for bkg hypothesis of redshift corrected stacked on-source event rate Bayesian Block data",100,psimintot-1.,psimaxtot+1.);
18191 }
18192 }
18193 }
18194 }
18195
18196 if (hPsiOff)
18197 {
18198 rbkg=(TH1F*)hPsiOff->Clone();
18199 rbkg->Reset();
18200 }
18201 else
18202 {
18203 if (bkg)
18204 {
18205 if (!zcor)
18206 {
18207 if (type.Contains("N"))
18208 {
18209 rbkg=new TH1F("hPsiOffBBtN","Psi distr. for bkg hypothesis of per time window normalized off-source event rate Bayesian Block data",100,psiminbkg-1.,psimaxbkg+1.);
18210 }
18211 else
18212 {
18213 rbkg=new TH1F("hPsiOffBBt","Psi distr. for bkg hypothesis of stacked off-source event rate Bayesian Block data",100,psiminbkg-1.,psimaxbkg+1.);
18214 }
18215 }
18216 if (zcor)
18217 {
18218 if (type.Contains("N"))
18219 {
18220 rbkg=new TH1F("hPsiOffBBztN","Psi distr. for bkg hypothesis of redshift corrected per time window normalized off-source event rate Bayesian Block data",100,psiminbkg-1.,psimaxbkg+1.);
18221 }
18222 else
18223 {
18224 rbkg=new TH1F("hPsiOffBBzt","Psi distr. for bkg hypothesis of redshift corrected stacked off-source event rate Bayesian Block data",100,psiminbkg-1.,psimaxbkg+1.);
18225 }
18226 }
18227 }
18228 }
18229
18230 if (tot)
18231 {
18232 pvaluetot=math.PsiPvalue(-1,nr,tot,0,0,freq,0,rtot,ncut,&nrxtot);
18233 fBurstHistos.Add(rtot);
18234 }
18235 if (bkg)
18236 {
18237 pvaluebkg=math.PsiPvalue(-1,nr,bkg,0,0,freq,0,rbkg,ncut,&nrxbkg);
18238 fBurstHistos.Add(rbkg);
18239 }
18240 }
18241
18242 // Restore the original histogram data
18243 if (tot)
18244 {
18245 for (Int_t i=1; i<=tot->GetNbinsX(); i++)
18246 {
18247 tot->AddBinContent(i,-1);
18248 }
18249 }
18250 if (bkg)
18251 {
18252 for (Int_t i=1; i<=bkg->GetNbinsX(); i++)
18253 {
18254 bkg->AddBinContent(i,-1);
18255 }
18256 }
18257 }
18258
18260 // On-source/Off-source event rate ratio histo Bayesian statistics //
18262 if (type=="BBrat")
18263 {
18264 if (!zcor) // Plain observed arrival times
18265 {
18266 rat=(TH1*)fBurstHistos.FindObject("hRatUBBtN");
18267 }
18268 else // Redshift corrected arrival times
18269 {
18270 rat=(TH1*)fBurstHistos.FindObject("hRatUBBztN");
18271 }
18272
18273 if (!rat)
18274 {
18275 printf(" === No data available === \n");
18276 return;
18277 }
18278
18279 psirat=math.PsiValue(rat,0,0,freq);
18280 psidif=psitot-psibkg;
18281
18282 // Extreme Psi values for a pure background hypothesis of the recorded arrival time entries
18283 psiminrat=math.PsiExtreme(rat,0,0,-2);
18284 if (psirat<psiminrat) psiminrat=psirat;
18285 psimaxrat=math.PsiExtreme(rat,0,0,-1);
18286 if (psimaxrat>psiminrat) psifracrat=(psimaxrat-psirat)/(psimaxrat-psiminrat);
18287
18288 // P-value determination
18289 if (nr>=0)
18290 {
18291 if (!zcor) // Plain observed arrival times
18292 {
18293 hPsiRat=(TH1F*)fBurstHistos.FindObject("hPsiRatUBBtN");
18294 }
18295 else // Redshift corrected arrival times
18296 {
18297 hPsiRat=(TH1F*)fBurstHistos.FindObject("hPsiRatUBBztN");
18298 }
18299
18300 if (hPsiRat)
18301 {
18302 rrat=(TH1F*)hPsiRat->Clone();
18303 rrat->Reset();
18304 }
18305 else
18306 {
18307 if (!zcor) rrat=new TH1F("hPsiRatUBBtN","Psi distr. for bkg hypothesis of on/off source event rate Bayesian Block data",100,psiminrat-1.,psimaxrat+1.);
18308 if (zcor) rrat=new TH1F("hPsiRatUBBztN","Psi distr. for bkg hypothesis of redshift corrected on/off source event rate Bayesian Block data",100,psiminrat-1.,psimaxrat+1.);
18309 }
18310
18311 pvaluerat=math.PsiPvalue(-1,nr,rat,0,0,freq,0,rrat,ncut,&nrxrat);
18312 fBurstHistos.Add(rrat);
18313 }
18314 }
18315
18317 // Opening angle histo Bayesian statistics //
18319 if (type=="angle")
18320 {
18321 tot=(TH1*)fBurstHistos.FindObject("hOna");
18322 bkg=(TH1*)fBurstHistos.FindObject("hOffa");
18323
18324 if (!tot) printf(" === No on source data available === \n");
18325 if (!bkg) printf(" === No off source data available === \n");
18326
18327 if (!tot && !bkg) return;
18328
18329 TF1 pdfa("pdfa","sin(x*acos(-1.)/180.)");
18330 if (tot) psitot=math.PsiValue(tot,0,&pdfa,freq);
18331 if (bkg) psibkg=math.PsiValue(bkg,0,&pdfa,freq);
18332 psidif=psitot-psibkg;
18333
18334 // Extreme Psi values for a pure background hypothesis of the recorded opening angle entries
18335 if (tot)
18336 {
18337 psimintot=math.PsiExtreme(tot,0,&pdfa,-2);
18338 if (psitot<psimintot) psimintot=psitot;
18339 psimaxtot=math.PsiExtreme(tot,0,&pdfa,-1);
18340 if (psimaxtot>psimintot) psifractot=(psimaxtot-psitot)/(psimaxtot-psimintot);
18341 }
18342 if (bkg)
18343 {
18344 psiminbkg=math.PsiExtreme(bkg,0,&pdfa,-2);
18345 if (psibkg<psiminbkg) psiminbkg=psibkg;
18346 psimaxbkg=math.PsiExtreme(bkg,0,&pdfa,-1);
18347 if (psimaxbkg>psiminbkg) psifracbkg=(psimaxbkg-psibkg)/(psimaxbkg-psiminbkg);
18348 }
18349
18350 // P-value determination
18351 if (nr>=0)
18352 {
18353 hPsiOn=(TH1F*)fBurstHistos.FindObject("hPsiOna");
18354 hPsiOff=(TH1F*)fBurstHistos.FindObject("hPsiOffa");
18355
18356 if (hPsiOn)
18357 {
18358 rtot=(TH1F*)hPsiOn->Clone();
18359 rtot->Reset();
18360 }
18361 else
18362 {
18363 if (tot) rtot=new TH1F("hPsiOna","Psi distr. for bkg hypothesis of on-source opening angle data",100,psimintot-1.,psimaxtot+1.);
18364 }
18365
18366 if (hPsiOff)
18367 {
18368 rbkg=(TH1F*)hPsiOff->Clone();
18369 rbkg->Reset();
18370 }
18371 else
18372 {
18373 if (bkg) rbkg=new TH1F("hPsiOffa","Psi distr. for bkg hypothesis of off-source opening angle data",100,psiminbkg-1.,psimaxbkg+1.);
18374 }
18375
18376 if (tot)
18377 {
18378 pvaluetot=math.PsiPvalue(-1,nr,tot,0,&pdfa,freq,0,rtot,ncut,&nrxtot);
18379 fBurstHistos.Add(rtot);
18380 }
18381 if (bkg)
18382 {
18383 pvaluebkg=math.PsiPvalue(-1,nr,bkg,0,&pdfa,freq,0,rbkg,ncut,&nrxbkg);
18384 fBurstHistos.Add(rbkg);
18385 }
18386 }
18387 }
18388
18390 // Cosine of opening angle histo Bayesian statistics //
18392 if (type=="cosa")
18393 {
18394 tot=(TH1*)fBurstHistos.FindObject("hOnCosa");
18395 bkg=(TH1*)fBurstHistos.FindObject("hOffCosa");
18396
18397 if (!tot) printf(" === No on source data available === \n");
18398 if (!bkg) printf(" === No off source data available === \n");
18399
18400 if (!tot && !bkg) return;
18401
18402 if (tot) psitot=math.PsiValue(tot,0,0,freq);
18403 if (bkg) psibkg=math.PsiValue(bkg,0,0,freq);
18404 psidif=psitot-psibkg;
18405
18406 // Extreme Psi values for a pure background hypothesis of the recorded cos(opening angle) entries
18407 if (tot)
18408 {
18409 psimintot=math.PsiExtreme(tot,0,0,-2);
18410 if (psitot<psimintot) psimintot=psitot;
18411 psimaxtot=math.PsiExtreme(tot,0,0,-1);
18412 if (psimaxtot>psimintot) psifractot=(psimaxtot-psitot)/(psimaxtot-psimintot);
18413 }
18414 if (bkg)
18415 {
18416 psiminbkg=math.PsiExtreme(bkg,0,0,-2);
18417 if (psibkg<psiminbkg) psiminbkg=psibkg;
18418 psimaxbkg=math.PsiExtreme(bkg,0,0,-1);
18419 if (psimaxbkg>psiminbkg) psifracbkg=(psimaxbkg-psibkg)/(psimaxbkg-psiminbkg);
18420 }
18421
18422 // P-value determination
18423 if (nr>=0)
18424 {
18425 hPsiOn=(TH1F*)fBurstHistos.FindObject("hPsiOnCosa");
18426 hPsiOff=(TH1F*)fBurstHistos.FindObject("hPsiOffCosa");
18427
18428 if (hPsiOn)
18429 {
18430 rtot=(TH1F*)hPsiOn->Clone();
18431 rtot->Reset();
18432 }
18433 else
18434 {
18435 if (tot) rtot=new TH1F("hPsiOnCosa","Psi distr. for bkg hypothesis of on-source cos(opening angle) data",100,psimintot-1.,psimaxtot+1.);
18436 }
18437
18438 if (hPsiOff)
18439 {
18440 rbkg=(TH1F*)hPsiOff->Clone();
18441 rbkg->Reset();
18442 }
18443 else
18444 {
18445 if (bkg) rbkg=new TH1F("hPsiOffCosa","Psi distr. for bkg hypothesis of off-source cos(opening angle) data",100,psiminbkg-1.,psimaxbkg+1.);
18446 }
18447
18448 if (tot)
18449 {
18450 pvaluetot=math.PsiPvalue(-1,nr,tot,0,0,freq,0,rtot,ncut,&nrxtot);
18451 fBurstHistos.Add(rtot);
18452 }
18453 if (bkg)
18454 {
18455 pvaluebkg=math.PsiPvalue(-1,nr,bkg,0,0,freq,0,rbkg,ncut,&nrxbkg);
18456 fBurstHistos.Add(rbkg);
18457 }
18458 }
18459 }
18460
18462 // BB of cos(opening angle) Bayesian statistics //
18464 if (type.Contains("BBcosa"))
18465 {
18466 if (!type.Contains("N"))
18467 {
18468 tot=(TH1*)fBurstHistos.FindObject("hOnBBa");
18469 bkg=(TH1*)fBurstHistos.FindObject("hOffBBa");
18470 }
18471 else
18472 {
18473 tot=(TH1*)fBurstHistos.FindObject("hOnBBaN");
18474 bkg=(TH1*)fBurstHistos.FindObject("hOffBBaN");
18475 }
18476
18477 if (!tot) printf(" === No on source data available === \n");
18478 if (!bkg) printf(" === No off source data available === \n");
18479
18480 if (!tot && !bkg) return;
18481
18482 // Temporarily offset the bin contents so that the lowest bin content is 1 for the psi analysis
18483 if (tot)
18484 {
18485 for (Int_t i=1; i<=tot->GetNbinsX(); i++)
18486 {
18487 tot->AddBinContent(i,1);
18488 }
18489 }
18490 if (bkg)
18491 {
18492 for (Int_t i=1; i<=bkg->GetNbinsX(); i++)
18493 {
18494 bkg->AddBinContent(i,1);
18495 }
18496 }
18497
18498 if (tot) psitot=math.PsiValue(tot,0,0,freq);
18499 if (bkg) psibkg=math.PsiValue(bkg,0,0,freq);
18500 psidif=psitot-psibkg;
18501
18502 // Extreme Psi values for a pure background hypothesis of the recorded arrival time entries
18503 if (tot)
18504 {
18505 psimintot=math.PsiExtreme(tot,0,0,-2);
18506 if (psitot<psimintot) psimintot=psitot;
18507 psimaxtot=math.PsiExtreme(tot,0,0,-1);
18508 if (psimaxtot>psimintot) psifractot=(psimaxtot-psitot)/(psimaxtot-psimintot);
18509 }
18510 if (bkg)
18511 {
18512 psiminbkg=math.PsiExtreme(bkg,0,0,-2);
18513 if (psibkg<psiminbkg) psiminbkg=psibkg;
18514 psimaxbkg=math.PsiExtreme(bkg,0,0,-1);
18515 if (psimaxbkg>psiminbkg) psifracbkg=(psimaxbkg-psibkg)/(psimaxbkg-psiminbkg);
18516 }
18517
18518 // P-value determination
18519 if (nr>=0)
18520 {
18521 hPsiOn=(TH1F*)fBurstHistos.FindObject("hPsiOnBBa");
18522 hPsiOff=(TH1F*)fBurstHistos.FindObject("hPsiOffBBa");
18523 if (type.Contains("N"))
18524 {
18525 hPsiOn=(TH1F*)fBurstHistos.FindObject("hPsiOnBBaN");
18526 hPsiOff=(TH1F*)fBurstHistos.FindObject("hPsiOffBBaN");
18527 }
18528
18529 if (hPsiOn)
18530 {
18531 rtot=(TH1F*)hPsiOn->Clone();
18532 rtot->Reset();
18533 }
18534 else
18535 {
18536 if (tot)
18537 {
18538 if (type.Contains("N"))
18539 {
18540 rtot=new TH1F("hPsiOnBBaN","Psi distr. for bkg hypothesis of per patch normalized on-source cos(opening angle) Bayesian Block data",100,psimintot-1.,psimaxtot+1.);
18541 }
18542 else
18543 {
18544 rtot=new TH1F("hPsiOnBBa","Psi distr. for bkg hypothesis of stacked on-source cos(opening angle) Bayesian Block data",100,psimintot-1.,psimaxtot+1.);
18545 }
18546 }
18547 }
18548
18549 if (hPsiOff)
18550 {
18551 rbkg=(TH1F*)hPsiOff->Clone();
18552 rbkg->Reset();
18553 }
18554 else
18555 {
18556 if (bkg)
18557 {
18558 if (type.Contains("N"))
18559 {
18560 rbkg=new TH1F("hPsiOffBBaN","Psi distr. for bkg hypothesis of per patch normalized off-source cos(opening angle) Bayesian Block data",100,psiminbkg-1.,psimaxbkg+1.);
18561 }
18562 else
18563 {
18564 rbkg=new TH1F("hPsiOffBBa","Psi distr. for bkg hypothesis of stacked off-source cos(opening angle) Bayesian Block data",100,psiminbkg-1.,psimaxbkg+1.);
18565 }
18566 }
18567 }
18568
18569 if (tot)
18570 {
18571 pvaluetot=math.PsiPvalue(-1,nr,tot,0,0,freq,0,rtot,ncut,&nrxtot);
18572 fBurstHistos.Add(rtot);
18573 }
18574 if (bkg)
18575 {
18576 pvaluebkg=math.PsiPvalue(-1,nr,bkg,0,0,freq,0,rbkg,ncut,&nrxbkg);
18577 fBurstHistos.Add(rbkg);
18578 }
18579 }
18580
18581 // Restore the original histogram data
18582 if (tot)
18583 {
18584 for (Int_t i=1; i<=tot->GetNbinsX(); i++)
18585 {
18586 tot->AddBinContent(i,-1);
18587 }
18588 }
18589 if (bkg)
18590 {
18591 for (Int_t i=1; i<=bkg->GetNbinsX(); i++)
18592 {
18593 bkg->AddBinContent(i,-1);
18594 }
18595 }
18596 }
18597
18599 // On-source/Off-source BB cos(opening angle) ratio Bayesian statistics //
18601 if (type=="BBrac")
18602 {
18603 rat=(TH1*)fBurstHistos.FindObject("hRatUBBaN");
18604
18605 if (!rat)
18606 {
18607 printf(" === No data available === \n");
18608 return;
18609 }
18610
18611 psirat=math.PsiValue(rat,0,0,freq);
18612 psidif=psitot-psibkg;
18613
18614 // Extreme Psi values for a pure background hypothesis of the recorded arrival time entries
18615 psiminrat=math.PsiExtreme(rat,0,0,-2);
18616 if (psirat<psiminrat) psiminrat=psirat;
18617 psimaxrat=math.PsiExtreme(rat,0,0,-1);
18618 if (psimaxrat>psiminrat) psifracrat=(psimaxrat-psirat)/(psimaxrat-psiminrat);
18619
18620 // P-value determination
18621 if (nr>=0)
18622 {
18623 hPsiRat=(TH1F*)fBurstHistos.FindObject("hPsiRatUBBaN");
18624
18625 if (hPsiRat)
18626 {
18627 rrat=(TH1F*)hPsiRat->Clone();
18628 rrat->Reset();
18629 }
18630 else
18631 {
18632 rrat=new TH1F("hPsiRatUBBaN","Psi distr. for bkg hypothesis of on/off source cos(opening angle) Bayesian Block data",100,psiminrat-1.,psimaxrat+1.);
18633 }
18634
18635 pvaluerat=math.PsiPvalue(-1,nr,rat,0,0,freq,0,rrat,ncut,&nrxrat);
18636 fBurstHistos.Add(rrat);
18637 }
18638 }
18639
18641 // Arrival time interval Bayesian statistics //
18643 if (type=="dt")
18644 {
18645 TH1F hOndt;
18646 TH1F hOffdt;
18647 TF1 pdfdttot;
18648 TF1 pdfdtbkg;
18649
18650 GetBurstDtDistributions(ndt,hOndt,pdfdttot,hOffdt,pdfdtbkg,zcor);
18651
18652 Int_t ntot=hOndt.GetEntries();
18653 Int_t nbkg=hOffdt.GetEntries();
18654
18655 if (!ntot) printf(" === No on source data available === \n");
18656 if (!nbkg) printf(" === No off source data available === \n");
18657
18658 if (!ntot && !nbkg) return;
18659
18660 if (ntot) psitot=math.PsiValue(&hOndt,0,&pdfdttot,freq);
18661 if (nbkg) psibkg=math.PsiValue(&hOffdt,0,&pdfdtbkg,freq);
18662 psidif=psitot-psibkg;
18663
18664 if (ntot)
18665 {
18666 psimintot=math.PsiExtreme(&hOndt,0,&pdfdttot,-2);
18667 if (psitot<psimintot) psimintot=psitot;
18668 psimaxtot=math.PsiExtreme(&hOndt,0,&pdfdttot,-1);
18669 if (psimaxtot>psimintot) psifractot=(psimaxtot-psitot)/(psimaxtot-psimintot);
18670 }
18671 if (nbkg)
18672 {
18673 psiminbkg=math.PsiExtreme(&hOffdt,0,&pdfdtbkg,-2);
18674 if (psibkg<psiminbkg) psiminbkg=psibkg;
18675 psimaxbkg=math.PsiExtreme(&hOffdt,0,&pdfdtbkg,-1);
18676 if (psimaxbkg>psiminbkg) psifracbkg=(psimaxbkg-psibkg)/(psimaxbkg-psiminbkg);
18677 }
18678
18679 // P-value determination
18680 if (nr>=0)
18681 {
18682 TString nametot;
18683 TString namebkg;
18684 if (!zcor)
18685 {
18686 nametot.Form("hPsiOndt%-i",ndt);
18687 namebkg.Form("hPsiOffdt%-i",ndt);
18688 }
18689 else
18690 {
18691 nametot.Form("hPsiOnZdt%-i",ndt);
18692 namebkg.Form("hPsiOffZdt%-i",ndt);
18693 }
18694
18695 TH1F* hPsiOn=(TH1F*)fBurstHistos.FindObject(nametot);
18696 TH1F* hPsiOff=(TH1F*)fBurstHistos.FindObject(namebkg);
18697
18698 TString title;
18699 if (hPsiOn)
18700 {
18701 rtot=(TH1F*)hPsiOn->Clone();
18702 rtot->Reset();
18703 }
18704 else
18705 {
18706 if (!zcor) title.Form("Psi distr. for bkg hypothesis of on-source dt data for n=%-i",ndt);
18707 if (zcor) title.Form("Psi distr. for bkg hypothesis of redshift corrected on-source dt data for n=%-i",ndt);
18708 if (ntot) rtot=new TH1F(nametot,title,100,psimintot-1.,psimaxtot+1.);
18709 }
18710
18711 if (hPsiOff)
18712 {
18713 rbkg=(TH1F*)hPsiOff->Clone();
18714 rbkg->Reset();
18715 }
18716 else
18717 {
18718 if (!zcor) title.Form("Psi distr. for bkg hypothesis of off-source dt data for n=%-i",ndt);
18719 if (zcor) title.Form("Psi distr. for bkg hypothesis of redshift corrected off-source dt data for n=%-i",ndt);
18720 if (nbkg) rbkg=new TH1F(namebkg,title,100,psiminbkg-1.,psimaxbkg+1.);
18721 }
18722
18723 if (ntot)
18724 {
18725 pvaluetot=math.PsiPvalue(-1,nr,&hOndt,0,&pdfdttot,freq,0,rtot,ncut,&nrxtot);
18726 fBurstHistos.Add(rtot);
18727 }
18728 if (nbkg)
18729 {
18730 pvaluebkg=math.PsiPvalue(-1,nr,&hOffdt,0,&pdfdtbkg,freq,0,rbkg,ncut,&nrxbkg);
18731 fBurstHistos.Add(rbkg);
18732 }
18733 }
18734 }
18735
18737 // Listing of the statistics results //
18739
18740 printf(" The following randomised Psi histograms have been (re)generated : \n");
18741 if (rtot) printf(" ... %-s : %-s \n",rtot->GetName(),rtot->GetTitle());
18742 if (rbkg) printf(" ... %-s : %-s \n",rbkg->GetName(),rbkg->GetTitle());
18743 if (rrat) printf(" ... %-s : %-s \n",rrat->GetName(),rrat->GetTitle());
18744
18745 text="stacked patches data:";
18746 if (type.Contains("N")) text="per patch normalized data:";
18747
18748 printf(" *** Observed Psi values (in dB) for the hypothesis of no burst signal *** \n");
18749 if (psitot>=0) printf(" For the on-source %-s psi=%-g \n",text.Data(),psitot);
18750 if (psibkg>=0) printf(" For the off-source %-s psi=%-g \n",text.Data(),psibkg);
18751 if (psitot>=0 && psibkg>=0) printf(" --> Difference between observed on-source and off-source psi values : %-g \n",psidif);
18752 if (psirat>=0)
18753 {
18754 if (type=="BBrat") printf(" For the patch normalized on/off source event rate Bayesian Blocks : psi=%-g \n",psirat);
18755 if (type=="BBrac") printf(" For the patch normalized on/off source cos(opening angle) Bayesian Blocks : psi=%-g \n",psirat);
18756 }
18757
18758 if (psimintot>=0 || psiminbkg>=0 || psiminrat>=0)
18759 {
18760 printf(" *** Extreme Psi values for the case of pure background *** \n");
18761 if (psimintot>=0)
18762 {
18763 printf(" For the on-source %-s psimin=%-g psimax=%-g",text.Data(),psimintot,psimaxtot);
18764 if (psifractot>0) printf(" (psimax-psi)/range=%-g",psifractot);
18765 printf("\n");
18766 }
18767 if (psiminbkg>=0)
18768 {
18769 printf(" For the off-source %-s psimin=%-g psimax=%-g",text.Data(),psiminbkg,psimaxbkg);
18770 if (psifracbkg>0) printf(" (psimax-psi)/range=%-g",psifracbkg);
18771 printf("\n");
18772 }
18773 if (psiminrat>=0)
18774 {
18775 if (type=="BBrat") printf(" For the patch normalized on/off source event rate Bayesian Blocks psimin= %-g psimax= %-g",psiminrat,psimaxrat);
18776 if (type=="BBrac") printf(" For the patch normalized on/off source cos(opening angle) Bayesian Blocks psimin= %-g psimax=%-g",psiminrat,psimaxrat);
18777 if (psifracrat>0) printf(" (psimax-psi)/range=%-g",psifracrat);
18778 printf("\n");
18779 }
18780 }
18781
18782 if (nr>=0)
18783 {
18784 printf(" *** P-values of the observed on-source and off-source psi values *** \n");
18785 if (nrxtot>0) printf(" For the on-source %-s P-value=%-g Used number of randomisations: %-g \n",text.Data(),pvaluetot,nrxtot);
18786 if (nrxbkg>0) printf(" For the off-source %-s P-value=%-g Used number of randomisations: %-g \n",text.Data(),pvaluebkg,nrxbkg);
18787 if (nrxrat>0)
18788 {
18789 if (type=="BBrat") printf(" For the patch normalized on/off source event rate Bayesian Blocks : P-value=%-g Used number of randomisations: %-g \n",pvaluerat,nrxrat);
18790 if (type=="BBrac") printf(" For the patch normalized on/off source cos(opening angle) Bayesian Blocks : P-value=%-g Used number of randomisations: %-g \n",pvaluerat,nrxrat);
18791 }
18792 }
18793}
18794
18795void NcAstrolab::GetBurstChi2Statistics(TString type,Int_t ndt,Bool_t zcor)
18796{
18842
18843 NcMath math;
18844
18845 TString text="none";
18846 if (type=="time") text="arrival time";
18847 if (type=="BBtime") text="stacked Bayesian Block event rate";
18848 if (type=="BBtimeN") text="per time window normalized Bayesian Block event rate";
18849 if (type=="BBrat") text="per time window normalized On-source/Off-source Bayesian Block event rate ratio";
18850 if (type=="angle") text="opening angle";
18851 if (type=="cosa") text="cos(opening angle)";
18852 if (type=="BBcosa") text="stacked Bayesian Block cos(opening angle)";
18853 if (type=="BBcosaN") text="per patch normalized Bayesian Block cos(opening angle)";
18854 if (type=="BBrac") text="per patch normalized On-source/Off-source Bayesian Block cos(opening angle) ratio";
18855 if (type=="dt") text="arrival time interval";
18856
18857 if (zcor)
18858 {
18859 text.ReplaceAll("arrival time","redshift corrected arrival time");
18860 text.ReplaceAll("event rate","redshift corrected event rate");
18861 }
18862
18863 if (text=="none")
18864 {
18865 printf("\n *%-s::GetBurstChi2Statistics* Unknown statistics type : %-s \n",ClassName(),type.Data());
18866 return;
18867 }
18868 else
18869 {
18870 printf("\n *%-s::GetBurstChi2Statistics* Analysis of %-s statistics \n",ClassName(),text.Data());
18871 }
18872
18873 TH1* tot=0;
18874 TH1* bkg=0;
18875 TH1* rat=0;
18876
18877 Int_t ndftot=0;
18878 Int_t ndfbkg=0;
18879 Int_t ndfrat=0;
18880 Float_t chitot=0;
18881 Float_t chibkg=0;
18882 Float_t chirat=0;
18883
18885 // Arrival time histo Chi-squared statistics //
18887 if (type=="time")
18888 {
18889 if (!zcor)
18890 {
18891 tot=(TH1*)fBurstHistos.FindObject("hOnt");
18892 bkg=(TH1*)fBurstHistos.FindObject("hOfft");
18893 }
18894 else
18895 {
18896 tot=(TH1*)fBurstHistos.FindObject("hOnZt");
18897 bkg=(TH1*)fBurstHistos.FindObject("hOffZt");
18898 }
18899
18900 if (!tot) printf(" === No on source data available === \n");
18901 if (!bkg) printf(" === No off source data available === \n");
18902
18903 if (!tot && !bkg) return;
18904
18905 if (tot) chitot=math.Chi2Value(tot,0,0,&ndftot);
18906 if (bkg) chibkg=math.Chi2Value(bkg,0,0,&ndfbkg);
18907 }
18908
18910 // Event rate histo Chi-squared statistics //
18912 if (type.Contains("BBtime"))
18913 {
18914 if (!zcor)
18915 {
18916 if (!type.Contains("N"))
18917 {
18918 tot=(TH1*)fBurstHistos.FindObject("hOnBBt");
18919 bkg=(TH1*)fBurstHistos.FindObject("hOffBBt");
18920 }
18921 else
18922 {
18923 tot=(TH1*)fBurstHistos.FindObject("hOnBBtN");
18924 bkg=(TH1*)fBurstHistos.FindObject("hOffBBtN");
18925 }
18926 }
18927 else
18928 {
18929 if (!type.Contains("N"))
18930 {
18931 tot=(TH1*)fBurstHistos.FindObject("hOnBBzt");
18932 bkg=(TH1*)fBurstHistos.FindObject("hOffBBzt");
18933 }
18934 else
18935 {
18936 tot=(TH1*)fBurstHistos.FindObject("hOnBBztN");
18937 bkg=(TH1*)fBurstHistos.FindObject("hOffBBztN");
18938 }
18939 }
18940
18941 if (!tot) printf(" === No on source data available === \n");
18942 if (!bkg) printf(" === No off source data available === \n");
18943
18944 if (!tot && !bkg) return;
18945
18946 if (tot) chitot=math.Chi2Value(tot,0,0,&ndftot);
18947 if (bkg) chibkg=math.Chi2Value(bkg,0,0,&ndfbkg);
18948 }
18949
18951 // On-source/Off-source event rate ratio histo Chi-squared statistics //
18953 if (type=="BBrat")
18954 {
18955 if (!zcor)
18956 {
18957 rat=(TH1*)fBurstHistos.FindObject("hRatUBBtN");
18958 }
18959 else
18960 {
18961 rat=(TH1*)fBurstHistos.FindObject("hRatUBBztN");
18962 }
18963
18964 if (!rat)
18965 {
18966 printf(" === No data available === \n");
18967 return;
18968 }
18969
18970 chirat=math.Chi2Value(rat,0,0,&ndfrat);
18971 }
18972
18974 // Opening angle histo Chi-squared statistics //
18976 if (type=="angle")
18977 {
18978 tot=(TH1*)fBurstHistos.FindObject("hOna");
18979 bkg=(TH1*)fBurstHistos.FindObject("hOffa");
18980
18981 if (!tot) printf(" === No on source data available === \n");
18982 if (!bkg) printf(" === No off source data available === \n");
18983
18984 if (!tot && !bkg) return;
18985
18986 TF1 pdf("pdf","sin(x*acos(-1.)/180.)");
18987 if (tot) chitot=math.Chi2Value(tot,0,&pdf,&ndftot);
18988 if (bkg) chibkg=math.Chi2Value(bkg,0,&pdf,&ndfbkg);
18989 }
18990
18992 // Cosine of opening angle histo Chi-squared statistics //
18994 if (type=="cosa")
18995 {
18996 tot=(TH1*)fBurstHistos.FindObject("hOnCosa");
18997 bkg=(TH1*)fBurstHistos.FindObject("hOffCosa");
18998
18999 if (!tot) printf(" === No on source data available === \n");
19000 if (!bkg) printf(" === No off source data available === \n");
19001
19002 if (!tot && !bkg) return;
19003
19004 if (tot) chitot=math.Chi2Value(tot,0,0,&ndftot);
19005 if (bkg) chibkg=math.Chi2Value(bkg,0,0,&ndfbkg);
19006 }
19007
19009 // BB of cos(opening angle) Chi-squared statistics //
19011 if (type.Contains("BBcosa"))
19012 {
19013 if (!type.Contains("N"))
19014 {
19015 tot=(TH1*)fBurstHistos.FindObject("hOnBBa");
19016 bkg=(TH1*)fBurstHistos.FindObject("hOffBBa");
19017 }
19018 else
19019 {
19020 tot=(TH1*)fBurstHistos.FindObject("hOnBBaN");
19021 bkg=(TH1*)fBurstHistos.FindObject("hOffBBaN");
19022 }
19023
19024 if (!tot) printf(" === No on source data available === \n");
19025 if (!bkg) printf(" === No off source data available === \n");
19026
19027 if (!tot && !bkg) return;
19028
19029 if (tot) chitot=math.Chi2Value(tot,0,0,&ndftot);
19030 if (bkg) chibkg=math.Chi2Value(bkg,0,0,&ndfbkg);
19031 }
19032
19034 // On-source/Off-source BB cos(opening angle) ratio Chi-squared statistics //
19036 if (type=="BBrac")
19037 {
19038 rat=(TH1*)fBurstHistos.FindObject("hRatUBBaN");
19039
19040 if (!rat)
19041 {
19042 printf(" === No data available === \n");
19043 return;
19044 }
19045
19046 chirat=math.Chi2Value(rat,0,0,&ndfrat);
19047 }
19048
19050 // Arrival time interval Chi-squared statistics //
19052 if (type=="dt")
19053 {
19054 TH1F hOndt;
19055 TH1F hOffdt;
19056 TF1 pdfdttot;
19057 TF1 pdfdtbkg;
19058
19059 GetBurstDtDistributions(ndt,hOndt,pdfdttot,hOffdt,pdfdtbkg,zcor);
19060
19061 Int_t ntot=hOndt.GetEntries();
19062 Int_t nbkg=hOffdt.GetEntries();
19063
19064 if (!ntot) printf(" === No on source data available === \n");
19065 if (!nbkg) printf(" === No off source data available === \n");
19066
19067 if (!ntot && !nbkg) return;
19068
19069 if (ntot) chitot=math.Chi2Value(&hOndt,0,&pdfdttot,&ndftot);
19070 if (nbkg) chibkg=math.Chi2Value(&hOffdt,0,&pdfdtbkg,&ndfbkg);
19071 }
19072
19073 // Listing of the statistics results
19074 Float_t chidif=chitot-chibkg;
19075 printf(" *** Observed Chi-squared values for the hypothesis of no burst signal *** \n");
19076 if (chitot>0) printf(" For the on-source stacked patches : chi2=%-g ndf=%-i \n",chitot,ndftot);
19077 if (chibkg>0) printf(" For the off-source stacked patches : chi2=%-g ndf=%-i \n",chibkg,ndfbkg);
19078 if (chitot>0 && chibkg>0) printf(" --> Difference between observed on-source and off-source chi2 values : %-g \n",chidif);
19079 if (chirat>0)
19080 {
19081 if (type=="BBrat") printf(" For the on/off source event rate Bayesian Blocks : chi2=%-g ndf=%-i \n",chirat,ndfrat);
19082 if (type=="BBrac") printf(" For the on/off source cos(opening angle) Bayesian Blocks : chi2=%-g ndf=%-i \n",chirat,ndfrat);
19083 }
19084
19085 Float_t ptot=-1;
19086 Float_t sigmatot=-1;
19087 Float_t pbkg=-1;
19088 Float_t sigmabkg=-1;
19089 Float_t prat=-1;
19090 Float_t sigmarat=-1;
19091
19092 if (chitot)
19093 {
19094 ptot=math.Chi2Pvalue(chitot,ndftot);
19095 sigmatot=math.Chi2Pvalue(chitot,ndftot,0,1);
19096 }
19097 if (chibkg)
19098 {
19099 pbkg=math.Chi2Pvalue(chibkg,ndfbkg);
19100 sigmabkg=math.Chi2Pvalue(chibkg,ndfbkg,0,1);
19101 }
19102 if (chirat)
19103 {
19104 prat=math.Chi2Pvalue(chirat,ndfrat);
19105 sigmarat=math.Chi2Pvalue(chirat,ndfrat,0,1);
19106 }
19107
19108 printf(" *** P-values of the observed on-source and off-source chi2 values *** \n");
19109 if (ptot>=0) printf(" For the on-source stacked patches : P-value=%-g (sigma=%-g) \n",ptot,sigmatot);
19110 if (pbkg>=0) printf(" For the off-source stacked patches : P-value=%-g (sigma=%-g) \n",pbkg,sigmabkg);
19111 if (prat>=0)
19112 {
19113 if (type=="BBrat") printf(" For the on/off source event rate Bayesian Blocks : P-value=%-g (sigma=%-g) \n ",prat,sigmarat);
19114 if (type=="BBrac") printf(" For the on/off source cos(opening angle) Bayesian Blocks : P-value=%-g (sigma=%-g) \n ",prat,sigmarat);
19115 }
19116}
19117
19118void NcAstrolab::GetBurstDtDistributions(Int_t ndt,TH1F& hisdtOn,TF1& pdfdtOn,TH1F& hisdtOff,TF1& pdfdtOff,Bool_t zcor)
19119{
19138
19139
19140 hisdtOn.Reset();
19141 hisdtOff.Reset();
19142
19143 Int_t fTunits=TMath::Nint(fBurstParameters->GetSignal("Tunits"));
19144 TString tu="days";
19145 if (fTunits==1) tu="hours";
19146 if (fTunits==2) tu="sec";
19147 if (fTunits==3) tu="ns";
19148 if (fTunits==4) tu="ps";
19149
19150 Float_t fTfact=fBurstParameters->GetSignal("Tfact");
19151
19152 TString nametot;
19153 TString namebkg;
19154 TString varname;
19155
19156 // Create the automatically binned delta t histograms
19157 if (!zcor)
19158 {
19159 nametot.Form("hOndt%-i",ndt);
19160 namebkg.Form("hOffdt%-i",ndt);
19161 varname="dtime";
19162 }
19163 else
19164 {
19165 nametot.Form("hOnZdt%-i",ndt);
19166 namebkg.Form("hOffZdt%-i",ndt);
19167 varname="dtimez";
19168 }
19169 TH1F* hOndt=(TH1F*)fBurstHistos.FindObject(nametot);
19170 TH1F* hOffdt=(TH1F*)fBurstHistos.FindObject(namebkg);
19171
19172 TString title;
19173 Double_t deltatbin=0;
19174 Int_t nOndt=0;
19175 Int_t nOffdt=0;
19176
19177 if (!hOndt)
19178 {
19179 NcSample sOndt=fBurstOnMatch.GetDtSample(varname,ndt);
19180 nOndt=sOndt.GetN();
19181
19182 if (nOndt)
19183 {
19184 hOndt=new TH1F(nametot,"histo",10000,1,0);
19185
19186 hOndt->SetBuffer(nOndt);
19187
19188 for (Int_t i=1; i<=nOndt; i++)
19189 {
19190 hOndt->Fill(sOndt.GetEntry(i,1));
19191 }
19192
19193 hOndt->BufferEmpty(1);
19194
19195 // Create title and labels for this delta t histograms
19196 deltatbin=hOndt->GetXaxis()->GetBinWidth(1);
19197 if (!zcor) title.Form("Time intervals between %-i consecutive events in the on-source time window;dt in %-s;Counts per %-.3g %-s",(ndt+1),tu.Data(),deltatbin,tu.Data());
19198 if (zcor) title.Form("Time intervals between %-i consecutive events in the redshift corrected on-source time window;dt in %-s;Counts per %-.3g %-s",(ndt+1),tu.Data(),deltatbin,tu.Data());
19199 hOndt->SetTitle(title);
19200
19201 fBurstHistos.Add(hOndt);
19202 }
19203 }
19204
19205 if (!hOffdt)
19206 {
19207 NcSample sOffdt=fBurstOffMatch.GetDtSample(varname,ndt);
19208 nOffdt=sOffdt.GetN();
19209
19210 if (nOffdt)
19211 {
19212 hOffdt=new TH1F(namebkg,"histo",10000,1,0);
19213
19214 hOffdt->SetBuffer(nOffdt);
19215
19216 for (Int_t i=1; i<=nOffdt; i++)
19217 {
19218 hOffdt->Fill(sOffdt.GetEntry(i,1));
19219 }
19220
19221 hOffdt->BufferEmpty(1);
19222
19223 // Create title and labels for this delta t histograms
19224 deltatbin=hOffdt->GetXaxis()->GetBinWidth(1);
19225 if (!zcor) title.Form("Time intervals between %-i consecutive events in the off-source time window;dt in %-s;Counts per %-.3g %-s",(ndt+1),tu.Data(),deltatbin,tu.Data());
19226 if (zcor) title.Form("Time intervals between %-i consecutive events in the redshift corrected off-source time window;dt in %-s;Counts per %-.3g %-s",(ndt+1),tu.Data(),deltatbin,tu.Data());
19227 hOffdt->SetTitle(title);
19228
19229 fBurstHistos.Add(hOffdt);
19230 }
19231 }
19232
19233 if (hOndt || hOffdt) cout << " The following arrival time interval (dt) histograms have been generated :" << endl;
19234 if (hOndt) cout << " ... " << hOndt->GetName() << " : " << hOndt->GetTitle() << endl;
19235 if (hOffdt) cout << " ... " << hOffdt->GetName() << " : " << hOffdt->GetTitle() << endl;
19236
19237 if (hOndt) hisdtOn=*hOndt;
19238 if (hOffdt) hisdtOff=*hOffdt;
19239
19240 // Creation of the Poisson based dt PDFs from the observed data for a background only hypothesis
19241
19242 Double_t rateOn=fBurstParameters->GetSignal("rateOn");
19243 Double_t rateOff=fBurstParameters->GetSignal("rateOff");
19244
19245 // Convert the event rates into the correct units
19246 rateOn*=fTfact;
19247 rateOff*=fTfact;
19248
19249 if (zcor) // Redshift corrected arrival times
19250 {
19251 Double_t nevt=fBurstOnMatch.GetN();
19252 Double_t tmin=fBurstOnMatch.GetMinimum(varname);
19253 Double_t tmax=fBurstOnMatch.GetMaximum(varname);
19254 Double_t twin=tmax-tmin;
19255 rateOn=0;
19256 if (twin) rateOn=nevt/twin;
19257 nevt=fBurstOffMatch.GetN();
19258 tmin=fBurstOffMatch.GetMinimum(varname);
19259 tmax=fBurstOffMatch.GetMaximum(varname);
19260 twin=tmax-tmin;
19261 rateOff=0;
19262 if (twin) rateOff=nevt/twin;
19263 }
19264
19265 // Determine the corresponding dt PDFs based on Poisson statistics
19266 // Only the bkg dt PDF is used, since this may be obtained from off-source measurements.
19267 // Using the total dt PDF would artificially lower the sensitivity due to possible signal events.
19268
19269 NcMath math;
19270 pdfdtOn=math.PoissonDtDist(rateOn,ndt); // Poisson dt pdf for the observed on source event rate
19271 pdfdtOff=math.PoissonDtDist(rateOff,ndt); // Poisson dt pdf for the observed off source event rate
19272
19273 if (!zcor)
19274 {
19275 nametot.Form("hpdfOndt%-i",ndt);
19276 namebkg.Form("hpdfOffdt%-i",ndt);
19277 }
19278 else
19279 {
19280 nametot.Form("hpdfOnZdt%-i",ndt);
19281 namebkg.Form("hpdfOffZdt%-i",ndt);
19282 }
19283 TH1* hpdfOndt=(TH1*)fBurstHistos.FindObject(nametot);
19284 TH1* hpdfOffdt=(TH1*)fBurstHistos.FindObject(namebkg);
19285
19286 Double_t xmaxfdt=1;
19287 Double_t deltatmax=0;
19288 if (hOndt)
19289 {
19290 deltatmax=hOndt->GetXaxis()->GetXmax();
19291 xmaxfdt=deltatmax;
19292 }
19293 if (hOffdt)
19294 {
19295 deltatmax=hOffdt->GetXaxis()->GetXmax();
19296 if (deltatmax>xmaxfdt) xmaxfdt=deltatmax;
19297 }
19298 Int_t npx=10000;
19299 pdfdtOn.SetRange(0,xmaxfdt);
19300 pdfdtOn.SetNpx(npx);
19301 pdfdtOff.SetRange(0,xmaxfdt);
19302 pdfdtOff.SetNpx(npx);
19303
19304 // Provide the dt PDFs as histograms in the output file
19305 if (!hpdfOndt && nOndt)
19306 {
19307 hpdfOndt=(TH1*)pdfdtOn.GetHistogram()->Clone();
19308 hpdfOndt->SetName(nametot.Data());
19309 title.Form("dt in %-s",tu.Data());
19310 hpdfOndt->GetXaxis()->SetTitle(title);
19311 fBurstHistos.Add(hpdfOndt);
19312 }
19313
19314 if (!hpdfOffdt && nOffdt)
19315 {
19316 hpdfOffdt=(TH1*)pdfdtOff.GetHistogram()->Clone();
19317 hpdfOffdt->SetName(namebkg.Data());
19318 hpdfOffdt->GetXaxis()->SetTitle(title);
19319 fBurstHistos.Add(hpdfOffdt);
19320 }
19321
19322 if (hpdfOndt || hpdfOffdt) cout << " The following arrival time interval (dt) PDFs have been generated :" << endl;
19323 if (hpdfOndt) cout << " ... " << hpdfOndt->GetName() << " : " << hpdfOndt->GetTitle() << endl;
19324 if (hpdfOffdt) cout << " ... " << hpdfOffdt->GetName() << " : " << hpdfOffdt->GetTitle() << endl;
19325}
19326
19328{
19338
19339 Int_t nh=fBurstHistos.GetEntries();
19340 cout << endl;
19341 cout << " =============== The following " << nh << " histograms have been generated ===============" << endl;
19342 for (Int_t ih=0; ih<nh; ih++)
19343 {
19344 TH1* hx=(TH1*)fBurstHistos.At(ih);
19345 if (!hx) continue;
19346 if (!hx->GetEntries()) continue;
19347 cout << " " << hx->GetName() << " : " << hx->GetTitle() << endl;
19348 }
19349 cout << " ===============================================================================" << endl;
19350}
19351
19352TH1* NcAstrolab::GetBurstHistogram(TString name) const
19353{
19363
19364 TH1* h=(TH1*)fBurstHistos.FindObject(name);
19365
19366 if (!h) printf(" *** Histogram %-s not found. *** \n",name.Data());
19367
19368 return h;
19369}
19370
19372{
19382
19383 // The output file for the produced histograms
19384 TFile fout(filename.Data(),"RECREATE","NcAstrolab analysis results");
19385
19386 // Write all the histos to the output file
19387 Int_t nh=fBurstHistos.GetEntries();
19388 for (Int_t ih=0; ih<nh; ih++)
19389 {
19390 TH1* hx=(TH1*)fBurstHistos.At(ih);
19391 if (!hx) continue;
19392 if (!hx->GetEntries()) continue;
19393 hx->Write();
19394 }
19395
19396 fout.Write();
19397
19398 cout << endl;
19399 cout << " *" << ClassName() << "::WriteBurstHistograms* All generated histograms have been written to file " << filename << endl;
19401}
19402
19404{
19413
19414 if (gROOT->IsBatch())
19415 {
19416 printf("\n *%-s::SkyMapPanel* GUI is not available in batch mode. \n",ClassName());
19417 return;
19418 }
19419
19420 // Select the lab timestamp as default
19421 fMapTS.SetMJD(fMJD,fJsec,fJns,fJps,"A");
19422
19423 // Import current Lab settings
19424 Double_t l=0;
19425 Double_t b=0;
19426 GetLabPosition(l,b,"deg");
19427 fMapLabLocL=l;
19428 fMapLabLocB=b;
19431 // Get the lab timestamp data in the text box
19432 UInt_t year=0;
19433 UInt_t month=0;
19434 UInt_t day=0;
19435 GetDate(kTRUE,0,&year,&month,&day);
19436 GetDayTimeString("UTC",3,0,0,&fMapTime);
19437 fMapDate.Form("%02i-%02i-%-i",day,month,year);
19438 fMapTime.ReplaceAll(" UTC","");
19440 fMapDateTime+="/";
19442
19443 // Re-invokation of the SkyMapPanel
19444 if (fSkyMapPanel)
19445 {
19446 // Import the current lab settings
19447 Int_t idx=1;
19448 TString names[9]={"User","IceCube","RNO-G","ARA","Amanda","WSRT","Astron","Greenwich","ARCA"};
19449 for (Int_t i=1; i<=9; i++)
19450 {
19451 if (names[i-1]==fExperiment) idx=i;
19452 }
19453 fMapLabE->Select(idx,kTRUE);
19454
19455 MapLocEnter();
19456
19457 // The Lab UTC time
19458 fMapTStimetype->Select(1,kTRUE);
19459 MapTimeType(10);
19460
19461 // Map all subwindows of main frame
19462 fSkyMapPanel->MapSubwindows();
19463
19464 // Initialize the layout algorithm
19465 fSkyMapPanel->Resize(fSkyMapPanel->GetDefaultSize());
19466
19467 // Map main frame
19468 fSkyMapPanel->MapWindow();
19469
19470 return;
19471 }
19472
19473 // New initialization of the SkyMapPanel
19474 UInt_t border=5;
19475 fSkyMapPanel=new TGMainFrame(gClient->GetRoot());
19476 fSkyMapPanel->SetWindowName("SkyMapPanel");
19477 fSkyMapPanel->Connect("CloseWindow()","NcAstrolab",this,"MapClose()");
19478
19479 // Define the various sub-frames and fill them with the various panels
19480 TGCompositeFrame* frames[4]={0,0,0,0};
19481 TGLayoutHints* layouts[4]={0,0,0,0};
19482
19483 // The Lab specification and timestamp frame
19484 frames[0]=new TGCompositeFrame(fSkyMapPanel,1,1,kHorizontalFrame|kSunkenFrame);
19485 layouts[0]=new TGLayoutHints(kLHintsExpandX,border,border,0,0);
19486 LabLocationPanel(frames[0]);
19487 TimestampPanel(frames[0]);
19488
19489 // The local reference and info frame
19490 frames[1]=new TGCompositeFrame(fSkyMapPanel,1,1,kHorizontalFrame|kSunkenFrame);
19491 layouts[1]=new TGLayoutHints(kLHintsExpandX,border,border,0,0);
19492 LabLocalFramePanel(frames[1]);
19493 InfoPanel(frames[1]);
19494
19495 // The entries frame
19496 frames[2]=new TGCompositeFrame(fSkyMapPanel,1,1,kHorizontalFrame|kSunkenFrame);
19497 layouts[2]=new TGLayoutHints(kLHintsExpandX,border,border,0,0);
19498 EntriesPanel(frames[2]);
19499
19500 // The drawing/listing options and command buttons frame
19501 frames[3]=new TGCompositeFrame(fSkyMapPanel,1,1,kHorizontalFrame|kSunkenFrame);
19502 layouts[3]=new TGLayoutHints(kLHintsExpandX,border,border,0,0);
19503 MapListOptionsPanel(frames[3]);
19504 CommandPanel(frames[3]);
19505
19506 // Add all subframes to the mainframe
19507 for (Int_t i=0; i<4; i++)
19508 {
19509 if (frames[i]) fSkyMapPanel->AddFrame(frames[i],layouts[i]);
19510 }
19511
19512 // Map all subwindows of main frame
19513 fSkyMapPanel->MapSubwindows();
19514
19515 // Initialize the layout algorithm
19516 fSkyMapPanel->Resize(fSkyMapPanel->GetDefaultSize());
19517
19518 // Map main frame
19519 fSkyMapPanel->MapWindow();
19520}
19521
19522void NcAstrolab::LabLocationPanel(TGCompositeFrame* frame)
19523{
19529
19530 if (!frame) return;
19531
19532 TGGroupFrame* panel=new TGGroupFrame(frame,"Lab longitude, latitude, experiment site and detector ID",kHorizontalFrame);
19533 panel->SetTitlePos(TGGroupFrame::kCenter);
19534 frame->AddFrame(panel);
19535
19536 // The lab longitude entry field
19537 fMapLabLBI[0]=new TGNumberEntryField(panel,-1,fMapLabLocL);
19538 fMapLabLBI[0]->SetToolTipText("Longitude");
19539 fMapLabLBI[0]->Connect("TextChanged(const char*)","NcAstrolab",this,"MapLocl(const char*)");
19540 fMapLabLBI[0]->Resize(65,20);
19541 panel->AddFrame(fMapLabLBI[0]);
19542
19543 // The lab latitude entry field
19544 fMapLabLBI[1]=new TGNumberEntryField(panel,-1,fMapLabLocB);
19545 fMapLabLBI[1]->SetToolTipText("Latitude");
19546 fMapLabLBI[1]->Connect("TextChanged(const char*)","NcAstrolab",this,"MapLocb(const char*)");
19547 fMapLabLBI[1]->Resize(65,20);
19548 panel->AddFrame(fMapLabLBI[1]);
19549
19550 // The lab longitude and latitude type selection box
19551 fMapLabU=new TGComboBox(panel);
19552 fMapLabU->Connect("Selected(Int_t)","NcAstrolab",this,"MapUloc(Int_t)");
19553 fMapLabU->AddEntry("deg",1);
19554 fMapLabU->AddEntry("dms",2);
19555 fMapLabU->AddEntry("hms",3);
19556 fMapLabU->AddEntry("rad",4);
19557 fMapLabU->Resize(50,20);
19558 panel->AddFrame(fMapLabU);
19559 fMapLabU->Select(1,kTRUE);
19560
19561 // The experiment name selection box
19562 fMapLabE=new TGComboBox(panel);
19563 fMapLabE->Connect("Selected(Int_t)","NcAstrolab",this,"MapExperiment(Int_t)");
19564 Int_t idx=1;
19565 TString names[9]={"User","IceCube","RNO-G","ARA","Amanda","WSRT","Astron","Greenwich","ARCA"};
19566 for (Int_t i=1; i<=9; i++)
19567 {
19568 fMapLabE->AddEntry(names[i-1],i);
19569 if (names[i-1]==fExperiment) idx=i;
19570 }
19571 fMapLabE->Resize(90,20);
19572 panel->AddFrame(fMapLabE);
19573 fMapLabE->Select(idx,kTRUE);
19574
19575 // The detector element ID field
19576 fMapLabLBI[2]=new TGNumberEntryField(panel,-1,fLabId,TGNumberFormat::kNESInteger);
19577 fMapLabLBI[2]->SetToolTipText("The (optional) detector element ID (0=global)");
19578 fMapLabLBI[2]->Connect("TextChanged(const char*)","NcAstrolab",this,"MapLocId(const char*)");
19579 fMapLabLBI[2]->Resize(40,20);
19580 panel->AddFrame(fMapLabLBI[2]);
19581
19582 // The button to enter the provided data
19583 TGTextButton* enter=new TGTextButton(panel,"Enter");
19584 enter->SetToolTipText("Enter the provided data");
19585 enter->Connect("Clicked()","NcAstrolab",this,"MapLocEnter()");
19586 TGLayoutHints* Lenter=new TGLayoutHints(kLHintsCenterX,10,0,0,0);
19587 panel->AddFrame(enter,Lenter);
19588
19589 MapLocEnter();
19590}
19591
19592void NcAstrolab::MapLocl(const char* text)
19593{
19599
19600 TString s=text;
19601 fMapLabLocL=s.Atof();
19602}
19603
19604void NcAstrolab::MapLocb(const char* text)
19605{
19611
19612 TString s=text;
19613 fMapLabLocB=s.Atof();
19614}
19615
19617{
19623
19624 TString s[4]={"deg","dms","hms","rad"};
19625 if (i<=4) fMapLabLocU=s[i-1];
19626}
19627
19629{
19635
19636 TString s[9]={"User","IceCube","RNO-G","ARA","Amanda","WSRT","Astron","Greenwich","ARCA"};
19637 if (i<=9) fMapLabExpName=s[i-1];
19638}
19639
19640void NcAstrolab::MapLocId(const char* text)
19641{
19647
19648 TString s=text;
19649 fMapLabId=s.Atoi();
19650}
19651
19653{
19659
19660 fSkyMapPanel->RequestFocus();
19661
19663
19664 if (fMapLabExpName=="User")
19665 {
19666 SetNameTitle("User","Virtual Lab for general use");
19667 MapLocId("0");
19668 printf("\n *** Settings adopted for a virtual lab for general use. *** \n");
19669 }
19670 else
19671 {
19674 // Update the longitude, latitude and detector ID selection boxes
19676 TString s;
19677 s.Form("%-.3f",fMapLabLocL);
19678 fMapLabLBI[0]->SetText(s);
19679 s.Form("%-.3f",fMapLabLocB);
19680 fMapLabLBI[1]->SetText(s);
19681 fMapLabU->Select(1,kTRUE);
19682 MapUloc(1);
19683 s.Form("%-i",fMapLabId);
19684 fMapLabLBI[2]->SetText(s);
19685 printf("\n *** Lab settings adopted for the %-s location. *** \n",fMapLabExpName.Data());
19686 }
19687
19688 // Update the local frame data for the selected lab
19689 TString val;
19690 for (Int_t i=0; i<6; i++)
19691 {
19692 val.Form("%-.2f",fAxes[i]);
19693 if (fMapLabLframe[i]) fMapLabLframe[i]->SetText(val);
19694 }
19695}
19696
19697void NcAstrolab::TimestampPanel(TGCompositeFrame* frame)
19698{
19704
19705 if (!frame) return;
19706
19707 TGGroupFrame* panel=new TGGroupFrame(frame,"Timestamp to be used for Entries, List and Map",kHorizontalFrame);
19708 panel->SetTitlePos(TGGroupFrame::kCenter);
19709 frame->AddFrame(panel);
19710
19711 // The Date/Time textbox
19712 fMapTSdatetime=new TGTextEntry(panel,fMapDateTime.Data());
19713 fMapTSdatetime->SetToolTipText("Date/Time as dd-mm-yyyy/hh:mm:ss.sss or MJD");
19714 fMapTSdatetime->Connect("TextChanged(const char*)","NcAstrolab",this,"MapDateTime(const char*)");
19715 fMapTSdatetime->SetAlignment(kTextRight);
19716 fMapTSdatetime->Resize(170,20);
19717 panel->AddFrame(fMapTSdatetime);
19718
19719 // The Time type selection box
19720 fMapTStimetype=new TGComboBox(panel);
19721 fMapTStimetype->Connect("Selected(Int_t)","NcAstrolab",this,"MapTimeType(Int_t)");
19722 fMapTStimetype->AddEntry("UTC",1);
19723 fMapTStimetype->AddEntry("LMT",2);
19724 fMapTStimetype->AddEntry("UT1",3);
19725 fMapTStimetype->AddEntry("MJD",4);
19726 fMapTStimetype->AddEntry("JD",5);
19727 fMapTStimetype->AddEntry("TJD",6);
19728 fMapTStimetype->AddEntry("Unix",7);
19729 fMapTStimetype->AddEntry("GPS",8);
19730 fMapTStimetype->AddEntry("TAI",9);
19731 fMapTStimetype->AddEntry("TT",10);
19732 fMapTStimetype->AddEntry("SysClock",11);
19733 fMapTStimetype->AddEntry("Lab",12);
19734 fMapTStimetype->AddEntry("EntryName",13);
19735 fMapTStimetype->Resize(100,20);
19736 panel->AddFrame(fMapTStimetype);
19737 fMapTStimetype->Select(1,kTRUE);
19738 MapTimeType(1);
19739
19740 // The Lab TS modification button
19741 TGTextButton* labTS=new TGTextButton(panel,"Store as Lab TS");
19742 labTS->SetToolTipText("Store the current selection as Lab timestamp");
19743 labTS->Connect("Clicked()","NcAstrolab",this,"MapLabTS()");
19744 TGLayoutHints* LlabTS=new TGLayoutHints(kLHintsCenterX,10,0,0,0);
19745 panel->AddFrame(labTS,LlabTS);
19746}
19747
19748void NcAstrolab::MapDateTime(const char* text)
19749{
19755
19756 fMapDateTime=text;
19757}
19758
19760{
19766
19767 TString s[13]={"UTC","LMT","UT1","MJD","JD","TJD","Unix","GPS","TAI","TT","SysClock","Lab","EntryName"};
19768
19769 if (i<=13) fMapTimeType=s[i-1];
19770
19771 if (fMapTimeType=="SysClock" || fMapTimeType=="Lab") SetMapTS();
19772 if (fMapTimeType=="MJD" || fMapTimeType=="JD" || fMapTimeType=="TJD" || fMapTimeType=="Unix" || fMapTimeType.Contains("Name")) fMapTSdatetime->SetText("");
19773}
19774
19776{
19782
19783 SetMapTS();
19784
19785 fSkyMapPanel->RequestFocus();
19786
19787 Int_t mjd,sec,ns;
19788 fMapTS.GetMJD(mjd,sec,ns);
19789 Int_t ps=fMapTS.GetPs();
19790 this->SetMJD(mjd,sec,ns,ps,"U");
19791
19792 printf("\n *** Lab timestamp modified *** \n");
19793}
19794
19795void NcAstrolab::LabLocalFramePanel(TGCompositeFrame* frame)
19796{
19802
19803 if (!frame) return;
19804
19805 TGGroupFrame* panel=new TGGroupFrame(frame,"Local frame axes orientations w.r.t. X0=South, Y0=East, Z0=Zenith)",kHorizontalFrame);
19806 panel->SetTitlePos(TGGroupFrame::kCenter);
19807 frame->AddFrame(panel);
19808
19809 // The local X-axis theta (=zenith) angle w.r.t. the MRF
19810 fMapLabLframe[0]=new TGNumberEntryField(panel,-1,fAxes[0]);
19811 fMapLabLframe[0]->SetToolTipText("Local X-axis zenith angle in deg");
19812 fMapLabLframe[0]->Resize(55,20);
19813 panel->AddFrame(fMapLabLframe[0]);
19814
19815 // The local X-axis phi angle w.r.t. the MRF
19816 fMapLabLframe[1]=new TGNumberEntryField(panel,-1,fAxes[1]);
19817 fMapLabLframe[1]->SetToolTipText("Local X-axis phi angle in deg");
19818 fMapLabLframe[1]->Resize(55,20);
19819 panel->AddFrame(fMapLabLframe[1]);
19820
19821 // The local Y-axis theta (=zenith) angle w.r.t. the MRF
19822 fMapLabLframe[2]=new TGNumberEntryField(panel,-1,fAxes[2]);
19823 fMapLabLframe[2]->SetToolTipText("Local Y-axis zenith angle in deg");
19824 fMapLabLframe[2]->Resize(55,20);
19825 panel->AddFrame(fMapLabLframe[2]);
19826
19827 // The local Y-axis phi angle w.r.t. the MRF
19828 fMapLabLframe[3]=new TGNumberEntryField(panel,-1,fAxes[3]);
19829 fMapLabLframe[3]->SetToolTipText("Local Y-axis phi angle in deg");
19830 fMapLabLframe[3]->Resize(55,20);
19831 panel->AddFrame(fMapLabLframe[3]);
19832
19833 // The local Z-axis theta (=zenith) angle w.r.t. the MRF
19834 fMapLabLframe[4]=new TGNumberEntryField(panel,-1,fAxes[4]);
19835 fMapLabLframe[4]->SetToolTipText("Local Z-axis zenith angle in deg");
19836 fMapLabLframe[4]->Resize(55,20);
19837 panel->AddFrame(fMapLabLframe[4]);
19838
19839 // The local Z-axis phi angle w.r.t. the MRF
19840 fMapLabLframe[5]=new TGNumberEntryField(panel,-1,fAxes[5]);
19841 fMapLabLframe[5]->SetToolTipText("Local Z-axis phi angle in deg");
19842 fMapLabLframe[5]->Resize(55,20);
19843 panel->AddFrame(fMapLabLframe[5]);
19844
19846
19847 // The button to enter the provided data
19848 TGTextButton* enter=new TGTextButton(panel,"Enter");
19849 enter->SetToolTipText("Enter the provided data");
19850 enter->Connect("Clicked()","NcAstrolab",this,"MapLabLframeEnter()");
19851 TGLayoutHints* Lenter=new TGLayoutHints(kLHintsLeft,10,0,0,0);
19852 panel->AddFrame(enter,Lenter);
19853}
19854
19856{
19864
19865 fSkyMapPanel->RequestFocus();
19866
19867 if (fMapLabExpName=="IceCube" || fMapLabExpName=="RNO-G" || fMapLabExpName=="Amanda")
19868 {
19869 printf("\n *** Local frame will NOT be changed for experiment site %-s *** \n",fMapLabExpName.Data());
19870
19871 // Update the local frame data for the selected lab
19872 TString val;
19873 for (Int_t i=0; i<6; i++)
19874 {
19875 val.Form("%-.2f",fAxes[i]);
19876 if (fMapLabLframe[i]) fMapLabLframe[i]->SetText(val);
19877 }
19878 return;
19879 }
19880
19881 for (Int_t i=0; i<6; i++)
19882 {
19883 fAxes[i]=fMapLabLframe[i]->GetNumber();
19884 }
19885
19886 SetLocalFrame(fAxes[0],fAxes[1],fAxes[2],fAxes[3],fAxes[4],fAxes[5]);
19887}
19888
19889void NcAstrolab::InfoPanel(TGCompositeFrame* frame)
19890{
19896
19897 if (!frame) return;
19898
19899 TGGroupFrame* panel=new TGGroupFrame(frame,"Informative output",kHorizontalFrame);
19900 panel->SetTitlePos(TGGroupFrame::kCenter);
19901 frame->AddFrame(panel);
19902
19903 // The info category selection box
19904 TGComboBox* cinfo=new TGComboBox(panel);
19905 cinfo->Connect("Selected(Int_t)","NcAstrolab",this,"MapCinfo(Int_t)");
19906 cinfo->AddEntry("Lab",1);
19907 cinfo->AddEntry("TSbox",2);
19908 cinfo->AddEntry("Entry",3);
19909 cinfo->AddEntry("Nstore",4);
19910 cinfo->Resize(60,20);
19911 panel->AddFrame(cinfo);
19912 cinfo->Select(1,kTRUE);
19913 MapCinfo(1);
19914
19915 // The lab info time type selection box
19916 TGComboBox* tinfo=new TGComboBox(panel);
19917 tinfo->Connect("Selected(Int_t)","NcAstrolab",this,"MapTinfo(Int_t)");
19918 tinfo->AddEntry("LAT/LAST",1);
19919 tinfo->AddEntry("LMT/LMST",2);
19920 tinfo->AddEntry("Julian",3);
19921 tinfo->AddEntry("UT1",4);
19922 tinfo->AddEntry("UTC",5);
19923 tinfo->AddEntry("TAI",6);
19924 tinfo->AddEntry("GPS",7);
19925 tinfo->AddEntry("TT",8);
19926 tinfo->AddEntry("Unix",9);
19927 tinfo->Resize(85,20);
19928 panel->AddFrame(tinfo);
19929 tinfo->Select(1,kTRUE);
19930 MapTinfo(1);
19931
19932 // The lab info longitude and latitude type selection box
19933 TGComboBox* uinfo=new TGComboBox(panel);
19934 uinfo->Connect("Selected(Int_t)","NcAstrolab",this,"MapUinfo(Int_t)");
19935 uinfo->AddEntry("deg",1);
19936 uinfo->AddEntry("dms",2);
19937 uinfo->AddEntry("hms",3);
19938 uinfo->AddEntry("rad",4);
19939 uinfo->Resize(50,20);
19940 panel->AddFrame(uinfo);
19941 uinfo->Select(1,kTRUE);
19942 MapUinfo(1);
19943
19944 // The entry name textbox
19945 TGTextEntry* mapiname=new TGTextEntry(panel,"");
19946 mapiname->SetToolTipText("Stored entry name for info");
19947 mapiname->Connect("TextChanged(const char*)","NcAstrolab",this,"MapIname(const char*)");
19948 mapiname->SetAlignment(kTextRight);
19949 mapiname->Resize(100,20);
19950 panel->AddFrame(mapiname);
19951
19952 // The info button
19953 TGTextButton* info=new TGTextButton(panel,"Info");
19954 info->Connect("Clicked()","NcAstrolab",this,"MapInfo()");
19955 info->SetToolTipText("Provide info on the specified item");
19956 TGLayoutHints* Linfo=new TGLayoutHints(kLHintsLeft,10,0,0,0);
19957 panel->AddFrame(info,Linfo);
19958}
19959
19961{
19967
19968 TString s[4]={"Lab","TS box","EntryName","Nstore"};
19969 if (i<=4) fMapCinfo=s[i-1];
19970}
19971
19973{
19979
19980 if (i==1)
19981 {
19982 fMapTinfo=-1;
19983 }
19984 else
19985 {
19986 fMapTinfo=i-1;
19987 }
19988}
19989
19991{
19997
19998 TString s[4]={"deg","dms","hms","rad"};
19999 if (i<=4) fMapUinfo=s[i-1];
20000}
20001
20002void NcAstrolab::MapIname(const char* text)
20003{
20009
20010 fMapIname=text;
20011}
20012
20014{
20020
20021 SetMapTS();
20022
20023 TString modes[9]={"LAT/LAST","LMT/LMST","Julian","UT1","UTC","TAI","GPS","TT","Unix"};
20024 TString datetime;
20025
20026 if (fMapCinfo=="Nstore")
20027 {
20028 Int_t nref=GetNsignals(0);
20029 Int_t nmeas=GetNsignals(1);
20030 Int_t ntot=nref+nmeas;
20031 printf("\n *** Info about the stored entries *** \n");
20032 printf(" Ntotal=%-i Nrefs=%-i Nmeas=%-i \n",ntot,nref,nmeas);
20033 }
20034 else if (fMapCinfo=="Lab")
20035 {
20036 if (fMapTinfo<3)
20037 {
20038 printf("\n *** Info about the current Lab settings *** \n");
20040 }
20041 else
20042 {
20043 printf("\n *** Info for the Lab timestamp *** \n");
20044 if (fMapTinfo==8)
20045 {
20046 printf(" Unix time : %-.12f \n",GetUnixTime());
20047 }
20048 else
20049 {
20050 datetime=GetDayTimeString(modes[fMapTinfo],12);
20051 printf(" %-s \n",datetime.Data());
20052 }
20053 }
20054 }
20055 else if (fMapCinfo.Contains("TS"))
20056 {
20057 printf("\n *** Info for the timestamp in the user selection box *** \n");
20058 if (fMapTinfo<3)
20059 {
20060 printf(" Lab time offset w.r.t. UT : "); PrintTime(fToffset,12); printf("\n");
20062 fMapTS.Date(4);
20063 }
20064 else
20065 {
20066 if (fMapTinfo==8)
20067 {
20068 printf(" Unix time : %-.12f \n",fMapTS.GetUnixTime());
20069 }
20070 else
20071 {
20072 datetime=fMapTS.GetDayTimeString(modes[fMapTinfo],12);
20073 printf(" %-s \n",datetime.Data());
20074 }
20075 }
20076 }
20077 else // Information of the specified entry name
20078 {
20079 NcSignal* sx=0;
20080 NcTimestamp* tx=0;
20081 sx=GetSignal(fMapIname,0);
20082 if(!sx) sx=GetSignal(fMapIname,1);
20083 if (sx)
20084 {
20085 printf("\n *** Info for entry : %-s *** \n",fMapIname.Data());
20086 sx->Data("sph",fMapUinfo);
20087 tx=sx->GetTimestamp();
20088 if (tx)
20089 {
20090 NcTimestamp tx2(*tx);
20092 if (fMapTinfo<3)
20093 {
20094 printf(" Lab time offset w.r.t. UT : "); PrintTime(fToffset,12); printf("\n");
20095 tx2.Date(fMapTinfo,fToffset);
20096 tx2.Date(4);
20097 }
20098 else
20099 {
20100 if (fMapTinfo==8)
20101 {
20102 printf(" Unix time : %-.12f \n",tx2.GetUnixTime());
20103 }
20104 else
20105 {
20106 datetime=tx2.GetDayTimeString(modes[fMapTinfo],12);
20107 printf(" %-s \n",datetime.Data());
20108 }
20109 }
20110 }
20111 }
20112 else
20113 {
20114 printf("\n *** No entry found with name : %-s *** \n",fMapIname.Data());
20115 }
20116 }
20117}
20118
20119void NcAstrolab::EntriesPanel(TGCompositeFrame* frame)
20120{
20126
20127 if (!frame) return;
20128
20129 TGGroupFrame* panel=new TGGroupFrame(frame,"Entries in (a,b) coordinates",kHorizontalFrame);
20130 panel->SetTitlePos(TGGroupFrame::kCenter);
20131 frame->AddFrame(panel);
20132
20133 // The a coordinate entry field
20134 TGNumberEntryField* ea=new TGNumberEntryField(panel,-1,0);
20135 ea->SetToolTipText("Angle a");
20136 ea->Connect("TextChanged(const char*)","NcAstrolab",this,"MapEa(const char*)");
20137 ea->Resize(100,20);
20138 panel->AddFrame(ea);
20139 MapEa("0");
20140
20141 // The a coordinate type selection box
20142 TGComboBox* ua=new TGComboBox(panel);
20143 ua->Connect("Selected(Int_t)","NcAstrolab",this,"MapUa(Int_t)");
20144 ua->AddEntry("deg",1);
20145 ua->AddEntry("dms",2);
20146 ua->AddEntry("hms",3);
20147 ua->AddEntry("rad",4);
20148 ua->AddEntry("hrs",5);
20149 ua->Resize(50,20);
20150 panel->AddFrame(ua);
20151 ua->Select(1,kTRUE);
20152 MapUa(1);
20153
20154 // The b coordinate entry field
20155 TGNumberEntryField* eb=new TGNumberEntryField(panel,-1,0);
20156 eb->SetToolTipText("Angle b");
20157 eb->Connect("TextChanged(const char*)","NcAstrolab",this,"MapEb(const char*)");
20158 eb->Resize(100,20);
20159 panel->AddFrame(eb);
20160 MapEb("0");
20161
20162 // The b coordinate type selection box
20163 TGComboBox* ub=new TGComboBox(panel);
20164 ub->Connect("Selected(Int_t)","NcAstrolab",this,"MapUb(Int_t)");
20165 ub->AddEntry("deg",1);
20166 ub->AddEntry("dms",2);
20167 ub->AddEntry("hms",3);
20168 ub->AddEntry("rad",4);
20169 ub->AddEntry("hrs",5);
20170 ub->Resize(50,20);
20171 panel->AddFrame(ub);
20172 ub->Select(1,kTRUE);
20173 MapUb(1);
20174
20175 TGComboBox* ecoords=new TGComboBox(panel);
20176 ecoords->Connect("Selected(Int_t)","NcAstrolab",this,"MapEcoord(Int_t)");
20177 ecoords->AddEntry("(ra,dec) (J2000)",1);
20178 ecoords->AddEntry("(ra,dec) (Mean)",2);
20179 ecoords->AddEntry("(ra,dec) (True)",3);
20180 ecoords->AddEntry("(ra,dec) (B1950)",4);
20181 ecoords->AddEntry("Galactic (l,b)",5);
20182 ecoords->AddEntry("Ecliptic (l,b)",6);
20183 ecoords->AddEntry("Horizon (azi,zen)",7);
20184 ecoords->AddEntry("ICR (l,b)",8);
20185 ecoords->AddEntry("Local (theta,phi)",9);
20186 ecoords->AddEntry("pdir (theta,phi)",10);
20187 ecoords->Resize(125,20);
20188 panel->AddFrame(ecoords);
20189 ecoords->Select(1,kTRUE);
20190 MapEcoord(1);
20191
20192 // The signal type
20193 TGComboBox* etypes=new TGComboBox(panel);
20194 etypes->Connect("Selected(Int_t)","NcAstrolab",this,"MapEtype(Int_t)");
20195 etypes->AddEntry("Meas",1);
20196 etypes->AddEntry("Ref",2);
20197 etypes->Resize(55,20);
20198 panel->AddFrame(etypes);
20199 etypes->Select(1,kTRUE);
20200 MapEtype(1);
20201
20202 // The (optional) signal name
20203 TGTextEntry* ename=new TGTextEntry(panel,"");
20204 ename->SetToolTipText("The (optional) entry name");
20205 ename->Connect("TextChanged(const char*)","NcAstrolab",this,"MapEname(const char*)");
20206 ename->SetAlignment(kTextRight);
20207 ename->Resize(100,20);
20208 panel->AddFrame(ename);
20209
20210 // The button to Enter the entry
20211 TGTextButton* enter=new TGTextButton(panel,"Enter");
20212 enter->SetToolTipText("Enter the provided entry");
20213 enter->Connect("Clicked()","NcAstrolab",this,"MapEnter()");
20214 TGLayoutHints* Lenter=new TGLayoutHints(kLHintsCenterX,10,0,0,0);
20215 panel->AddFrame(enter,Lenter);
20216
20217 // The button to Remove the entry
20218 TGTextButton* remove=new TGTextButton(panel,"Remove");
20219 remove->SetToolTipText("Remove the entry specified by type and name pattern (name=* means all)");
20220 remove->Connect("Clicked()","NcAstrolab",this,"MapRemove()");
20221 TGLayoutHints* Lremove=new TGLayoutHints(kLHintsCenterX,10,0,0,0);
20222 panel->AddFrame(remove,Lremove);
20223}
20224
20225void NcAstrolab::MapEa(const char* text)
20226{
20232
20233 TString s=text;
20234 fMapEa=s.Atof();
20235}
20236
20238{
20244
20245 TString s[5]={"deg","dms","hms","rad","hrs"};
20246 if (i<=5) fMapEua=s[i-1];
20247}
20248
20249void NcAstrolab::MapEb(const char* text)
20250{
20256
20257 TString s=text;
20258 fMapEb=s.Atof();
20259}
20260
20262{
20268
20269 TString s[5]={"deg","dms","hms","rad","hrs"};
20270 if (i<=5) fMapEub=s[i-1];
20271}
20272
20274{
20280
20281 TString system[10]={"equ","equ","equ","equ","gal","ecl","hor","icr","loc","pdir"};
20282 TString mode[4]={"J","M","T","B"};
20283
20284 if (i<=10) fMapEcoord=system[i-1];
20285
20286 if (i<=4) fMapEmode=mode[i-1];
20287}
20288
20290{
20296
20297 fMapEtype=1;
20298 if (i==2) fMapEtype=0;
20299}
20300
20301void NcAstrolab::MapEname(const char* text)
20302{
20308
20309 fMapEname=text;
20310}
20311
20313{
20319
20320 SetMapTS(); // Set the selected timestamp
20321
20322 fSkyMapPanel->RequestFocus();
20323
20325
20326 printf("\n *** Specified entry stored *** \n");
20327}
20328
20330{
20336
20337 SetMapTS(); // Set the selected timestamp
20338
20339 fSkyMapPanel->RequestFocus();
20340
20341 Int_t nrem=0;
20343
20344 printf("\n *** Number of specified entries have been removed : %-i *** \n",nrem);
20345}
20346
20347void NcAstrolab::MapListOptionsPanel(TGCompositeFrame* frame)
20348{
20354
20355 if (!frame) return;
20356
20357 TGGroupFrame* panel=new TGGroupFrame(frame,"Map/List options for the (a,b) coordinates",kHorizontalFrame);
20358 panel->SetTitlePos(TGGroupFrame::kCenter);
20359 frame->AddFrame(panel);
20360
20361 // A frame with various additional settings
20362 TGVerticalFrame* render=new TGVerticalFrame(panel,1,1);
20363 panel->AddFrame(render);
20364
20365 // The coordinate system selection box
20366 TGGroupFrame* coordsys=new TGGroupFrame(render,"Coordinate system",kHorizontalFrame);
20367 coordsys->SetTitlePos(TGGroupFrame::kCenter);
20368 render->AddFrame(coordsys);
20369 TGComboBox* dcoords=new TGComboBox(coordsys);
20370 dcoords->Connect("Selected(Int_t)","NcAstrolab",this,"MapDcoord(Int_t)");
20371 dcoords->AddEntry("Equatorial (J2000)",1);
20372 dcoords->AddEntry("Equatorial (Mean)",2);
20373 dcoords->AddEntry("Equatorial (True)",3);
20374 dcoords->AddEntry("Equatorial (B1950)",4);
20375 dcoords->AddEntry("Galactic",5);
20376 dcoords->AddEntry("Ecliptic",6);
20377 dcoords->AddEntry("Horizon",7);
20378 dcoords->AddEntry("ICR",8);
20379 dcoords->AddEntry("Local",9);
20380 dcoords->Resize(140,20);
20381 coordsys->AddFrame(dcoords);
20382 dcoords->Select(1,kTRUE);
20383 MapDcoord(1);
20384
20385 // The Map representation selection box
20386 TGGroupFrame* mapview=new TGGroupFrame(render,"Map representation",kHorizontalFrame);
20387 mapview->SetTitlePos(TGGroupFrame::kCenter);
20388 render->AddFrame(mapview);
20389 TGComboBox* projs=new TGComboBox(mapview);
20390 projs->Connect("Selected(Int_t)","NcAstrolab",this,"MapProj(Int_t)");
20391 projs->AddEntry("Hammer projection",1);
20392 projs->AddEntry("Aitoff projection",2);
20393 projs->AddEntry("Mercator projection",3);
20394 projs->AddEntry("sin(b) vs. a",4);
20395 projs->AddEntry("b vs. a",5);
20396 projs->AddEntry("b vs. UT (0-24 hrs)",6);
20397 projs->AddEntry("b vs. LT (0-24 hrs)",7);
20398 projs->AddEntry("b vs. GST (0-24 hrs)",8);
20399 projs->AddEntry("b vs. LST (0-24 hrs)",9);
20400 projs->AddEntry("b vs. Day at UT",10);
20401 projs->AddEntry("b vs. Day at LT",11);
20402 projs->AddEntry("b vs. Day at GST",12);
20403 projs->AddEntry("b vs. Day at LST",13);
20404 projs->Resize(150,20);
20405 mapview->AddFrame(projs);
20406 projs->Select(1,kTRUE);
20407 MapProj(1);
20408
20409 // The meridian representation options
20410 TGGroupFrame* meridian=new TGGroupFrame(render,"Meridian ordering",kHorizontalFrame);
20411 meridian->SetTitlePos(TGGroupFrame::kCenter);
20412 render->AddFrame(meridian);
20413
20414 // The meridian mode selection box
20415 TGComboBox* mermode=new TGComboBox(meridian);
20416 mermode->Connect("Selected(Int_t)","NcAstrolab",this,"MapMerMode(Int_t)");
20417 mermode->AddEntry("Auto",1);
20418 mermode->AddEntry("---->",2);
20419 mermode->AddEntry("<----",3);
20420 mermode->Resize(55,20);
20421 meridian->AddFrame(mermode);
20422 mermode->Select(1,kTRUE);
20423 MapMerMode(1);
20424
20425 // The meridian central value
20426 TGNumberEntryField* merc=new TGNumberEntryField(meridian,-1,0);
20427 merc->SetToolTipText("Central meridian position");
20428 merc->Connect("TextChanged(const char*)","NcAstrolab",this,"MapMerC(const char*)");
20429 merc->Resize(65,20);
20430 meridian->AddFrame(merc);
20431 MapMerC("0");
20432
20433 // The meridian central value type selection box
20434 TGComboBox* meruc=new TGComboBox(meridian);
20435 meruc->Connect("Selected(Int_t)","NcAstrolab",this,"MapMerUc(Int_t)");
20436 meruc->AddEntry("deg",1);
20437 meruc->AddEntry("dms",2);
20438 meruc->AddEntry("hms",3);
20439 meruc->AddEntry("rad",4);
20440 meruc->Resize(50,20);
20441 meridian->AddFrame(meruc);
20442 meruc->Select(1,kTRUE);
20443 MapMerUc(1);
20444
20445 // The options group
20446 TGVButtonGroup* options=new TGVButtonGroup(panel,"Options");
20447 options->SetTitlePos(TGGroupFrame::kCenter);
20448 options->Connect("Clicked(Int_t)","NcAstrolab",this,"MapDoptions(Int_t)");
20449 TGCheckButton* bhist=new TGCheckButton(options,"Hist");
20450 bhist->SetToolTipText("Project data in a histogram");
20451 TGCheckButton* bclr=new TGCheckButton(options,"Clr");
20452 bclr->SetToolTipText("Clear display before drawing");
20453 TGCheckButton* bref=new TGCheckButton(options,"Ref");
20454 bref->SetToolTipText("Display reference signals");
20455 TGCheckButton* bmeas=new TGCheckButton(options,"Meas");
20456 bmeas->SetToolTipText("Display measured signals");
20457 TGCheckButton* brefts=new TGCheckButton(options,"RefTS");
20458 brefts->SetToolTipText("Display/list each reference signal using its actual recorded timestamp");
20459 panel->AddFrame(options);
20460 options->Show();
20461 options->SetButton(1,kFALSE);
20462 options->SetButton(2,kTRUE);
20463 options->SetButton(3,kTRUE);
20464 options->SetButton(4,kTRUE);
20465 options->SetButton(5,kFALSE);
20466 fMapDoptions[0]=kFALSE;
20467 fMapDoptions[1]=kTRUE;
20468 fMapDoptions[2]=kTRUE;
20469 fMapDoptions[3]=kTRUE;
20470 fMapDoptions[4]=kFALSE;
20471
20472 // The Nmax entry field
20473 TGNumberEntryField* nmax=new TGNumberEntryField(options,-1,-1,TGNumberFormat::kNESInteger);
20474 nmax->SetToolTipText("Max. number of Drawn/Listed entries per type (-1=all)");
20475 nmax->Connect("TextChanged(const char*)","NcAstrolab",this,"MapNmax(const char*)");
20476 nmax->Resize(40,20);
20477 options->AddFrame(nmax);
20478 MapNmax("-1");
20479
20480 // The signal name pattern for matching
20481 TGTextEntry* sname=new TGTextEntry(options,"*");
20482 sname->SetToolTipText("The requested entry name pattern (*=all)");
20483 sname->Connect("TextChanged(const char*)","NcAstrolab",this,"MapDname(const char*)");
20484 sname->SetAlignment(kTextRight);
20485 sname->Resize(100,20);
20486 TGLayoutHints* Lsname=new TGLayoutHints(kLHintsLeft,0,0,5,0);
20487 options->AddFrame(sname,Lsname);
20488 MapDname("*");
20489
20490 // The Ndigs entry field
20491 TGNumberEntryField* ndigs=new TGNumberEntryField(options,-1,1,TGNumberFormat::kNESInteger);
20492 ndigs->SetToolTipText("Number of digits for the listed entries");
20493 ndigs->Connect("TextChanged(const char*)","NcAstrolab",this,"MapNdigs(const char*)");
20494 ndigs->Resize(40,20);
20495 options->AddFrame(ndigs);
20496 MapNdigs("1");
20497
20498 // A frame with various additional settings
20499 TGVerticalFrame* others=new TGVerticalFrame(panel,1,1);
20500 panel->AddFrame(others);
20501
20502 // The Marker size frame
20503 TGGroupFrame* markers=new TGGroupFrame(others,"Marker settings",kHorizontalFrame);
20504 markers->SetTitlePos(TGGroupFrame::kCenter);
20505 others->AddFrame(markers);
20506
20507 // The marker size
20508 TGNumberEntryField* marksize=new TGNumberEntryField(markers,-1,1);
20509 marksize->SetToolTipText("Marker size");
20510 marksize->Connect("TextChanged(const char*)","NcAstrolab",this,"MapMarkSize(const char*)");
20511 marksize->Resize(40,20);
20512 markers->AddFrame(marksize);
20513 MapMarkSize("1");
20514
20515 // The marker style
20516 TGComboBox* markstyle=new TGComboBox(markers);
20517 markstyle->Connect("Selected(Int_t)","NcAstrolab",this,"MapMarkStyle(Int_t)");
20518 markstyle->AddEntry("Dot",1);
20519 markstyle->AddEntry("Star",2);
20520 markstyle->AddEntry("Square",3);
20521 markstyle->AddEntry("Utriangle",4);
20522 markstyle->AddEntry("Dtriangle",5);
20523 markstyle->AddEntry("Diamond",6);
20524 markstyle->AddEntry("Cross",7);
20525 markstyle->AddEntry("Ast",8);
20526 markstyle->AddEntry("Plus",9);
20527 markstyle->AddEntry("Times",10);
20528 markstyle->AddEntry("Circle",11);
20529 markstyle->AddEntry("oStar",12);
20530 markstyle->AddEntry("oSquare",13);
20531 markstyle->AddEntry("oUtriangle",14);
20532 markstyle->AddEntry("oDtriangle",15);
20533 markstyle->AddEntry("oDiamond",16);
20534 markstyle->AddEntry("oCross",17);
20535 markstyle->Resize(90,20);
20536 markers->AddFrame(markstyle);
20537 markstyle->Select(1,kTRUE);
20538 MapMarkStyle(1);
20539
20540 // The marker color selection box
20541 TGComboBox* markcolor=new TGComboBox(markers);
20542 markcolor->Connect("Selected(Int_t)","NcAstrolab",this,"MapMarkColor(Int_t)");
20543 markcolor->AddEntry("Black",1);
20544 markcolor->AddEntry("Red",2);
20545 markcolor->AddEntry("Blue",3);
20546 markcolor->AddEntry("Green",4);
20547 markcolor->AddEntry("Yellow",5);
20548 markcolor->AddEntry("Magenta",6);
20549 markcolor->AddEntry("Cyan",7);
20550 markcolor->AddEntry("Orange",8);
20551 markcolor->AddEntry("Violet",9);
20552 markcolor->AddEntry("Pink",10);
20553 markcolor->AddEntry("Azure",11);
20554 markcolor->AddEntry("Spring",12);
20555 markcolor->AddEntry("Teal",13);
20556 markcolor->AddEntry("Gray",14);
20557 markcolor->AddEntry("White",15);
20558 markcolor->Resize(80,20);
20559 markers->AddFrame(markcolor);
20560 markcolor->Select(3,kTRUE);
20561 MapMarkColor(3);
20562
20563 // The marker type selection box
20564 TGComboBox* marktype=new TGComboBox(markers);
20565 marktype->Connect("Selected(Int_t)","NcAstrolab",this,"MapMarkType(Int_t)");
20566 marktype->AddEntry("Ref",1);
20567 marktype->AddEntry("Meas",2);
20568 marktype->AddEntry("GC",3);
20569 marktype->AddEntry("Grid",4);
20570 marktype->Resize(55,20);
20571 markers->AddFrame(marktype);
20572 marktype->Select(2,kTRUE);
20573 MapMarkType(2);
20574
20575 // The Solar system group
20576 TGGroupFrame* solar=new TGGroupFrame(others,"Selection of Solar system reference objects",kHorizontalFrame);
20577 solar->SetTitlePos(TGGroupFrame::kCenter);
20578 others->AddFrame(solar);
20579
20580 TGButtonGroup* Ssolar=new TGButtonGroup(solar,0,3,5);
20581 Ssolar->SetTitlePos(TGGroupFrame::kCenter);
20582 Ssolar->Connect("Clicked(Int_t)","NcAstrolab",this,"MapSolar(Int_t)");
20583 TGCheckButton* bsun=new TGCheckButton(Ssolar,"Sun");
20584 bsun->SetToolTipText("Enter/Remove the Sun as a reference entry");
20585 TGCheckButton* bmoon=new TGCheckButton(Ssolar,"Moon");
20586 bmoon->SetToolTipText("Enter/Remove the Moon as a reference entry");
20587 TGCheckButton* bmercury=new TGCheckButton(Ssolar,"Mercury");
20588 bmercury->SetToolTipText("Enter/Remove Mercury as a reference entry");
20589 TGCheckButton* bvenus=new TGCheckButton(Ssolar,"Venus");
20590 bvenus->SetToolTipText("Enter/Remove Venus as a reference entry");
20591 TGCheckButton* bearth=new TGCheckButton(Ssolar,"Earth");
20592 bearth->SetToolTipText("Enter/Remove the Earth as a reference entry");
20593 TGCheckButton* bmars=new TGCheckButton(Ssolar,"Mars");
20594 bmars->SetToolTipText("Enter/Remove Mars as a reference entry");
20595 TGCheckButton* bjupiter=new TGCheckButton(Ssolar,"Jupiter");
20596 bjupiter->SetToolTipText("Enter/Remove Jupiter as a reference entry");
20597 TGCheckButton* bsaturn=new TGCheckButton(Ssolar,"Saturn");
20598 bsaturn->SetToolTipText("Enter/Remove Saturn as a reference entry");
20599 TGCheckButton* buranus=new TGCheckButton(Ssolar,"Uranus");
20600 buranus->SetToolTipText("Enter/Remove Uranus as a reference entry");
20601 TGCheckButton* bneptune=new TGCheckButton(Ssolar,"Neptune");
20602 bneptune->SetToolTipText("Enter/Remove Neptune as a reference entry");
20603 solar->AddFrame(Ssolar);
20604 Ssolar->Show();
20605 Ssolar->SetButton(1,kFALSE);
20606 Ssolar->SetButton(2,kFALSE);
20607 Ssolar->SetButton(3,kFALSE);
20608 Ssolar->SetButton(4,kFALSE);
20609 Ssolar->SetButton(5,kFALSE);
20610 Ssolar->SetButton(6,kFALSE);
20611 Ssolar->SetButton(7,kFALSE);
20612 Ssolar->SetButton(8,kFALSE);
20613 Ssolar->SetButton(9,kFALSE);
20614 Ssolar->SetButton(10,kFALSE);
20615 for (Int_t i=0; i<10; i++)
20616 {
20617 fMapSolar[i]=kFALSE;
20618 }
20619
20620 // The Solar system Enter and Remove command buttons
20621 TGVerticalFrame* comms=new TGVerticalFrame(solar,1,1);
20622 TGLayoutHints* Lcomms=new TGLayoutHints(kLHintsLeft,10,0,15,0);
20623 solar->AddFrame(comms,Lcomms); // Command buttons
20624
20625 // The button to Enter the solar system entries
20626 TGTextButton* enter=new TGTextButton(comms,"Enter");
20627 enter->SetToolTipText("Enter the selected Solar system objects as reference signals");
20628 enter->Connect("Clicked()","NcAstrolab",this,"MapEnterSolar()");
20629 TGLayoutHints* Lenter=new TGLayoutHints(kLHintsCenterX,0,0,10,15);
20630 comms->AddFrame(enter,Lenter);
20631
20632 // The button to Remove the solar system entries
20633 TGTextButton* remove=new TGTextButton(comms,"Remove");
20634 remove->SetToolTipText("Remove the selected Solar system objects from the reference signals");
20635 remove->Connect("Clicked()","NcAstrolab",this,"MapRemoveSolar()");
20636 TGLayoutHints* Lremove=new TGLayoutHints(kLHintsCenterX,0,0,0,0);
20637 comms->AddFrame(remove,Lremove);
20638}
20639
20641{
20647
20648 TString system[9]={"equ","equ","equ","equ","gal","ecl","hor","icr","loc"};
20649 TString mode[4]={"J","M","T","B"};
20650
20651 if (i<=9) fMapDcoord=system[i-1];
20652
20653 if (i<=4) fMapDmode=mode[i-1];
20654}
20655
20657{
20663
20664 TString s[13]={"ham","ait","mer","ang","cyl","UTh","LTh","GSTh","LSTh","UYh","LYh","GSYh","LSYh"};
20665 TString sh[13]={"hamh","aith","merh","angh","cylh","UTh","LTh","GSTh","LSTh","UYh","LYh","GSYh","LSYh"};
20666 if (!fMapDoptions[0] && i<13) fMapProj=s[i-1];
20667 if (fMapDoptions[0] && i<13) fMapProj=sh[i-1];
20668 for (Int_t k=0; k<13; k++)
20669 {
20670 if (fMapDoptions[0] && fMapProj==s[k]) fMapProj=sh[k];
20671 if (!fMapDoptions[0] && fMapProj==sh[k]) fMapProj=s[k];
20672 }
20673}
20674
20676{
20682
20683 Int_t modes[3]={0,1,-1};
20684 if (i<=3) fMapMerMode=modes[i-1];
20685}
20686
20687void NcAstrolab::MapMerC(const char* text)
20688{
20694
20695 TString s=text;
20696 fMapMerC=s.Atof();
20697}
20698
20700{
20706
20707 TString s[4]={"deg","dms","hms","rad"};
20708 if (i<=4) fMapMerUc=s[i-1];
20709}
20710
20712{
20718
20719 if (i>5) return;
20720
20721 if (!fMapDoptions[i-1])
20722 {
20723 fMapDoptions[i-1]=1;
20724 }
20725 else
20726 {
20727 fMapDoptions[i-1]=0;
20728 }
20729 if (i==1) MapProj(14); // Set histogram selection
20730}
20731
20732void NcAstrolab::MapNmax(const char* text)
20733{
20739
20740 TString s=text;
20741 fMapNmax=s.Atoi();
20742}
20743
20744void NcAstrolab::MapNdigs(const char* text)
20745{
20751
20752 TString s=text;
20753 fMapNdigs=s.Atoi();
20754}
20755
20756void NcAstrolab::MapDname(const char* text)
20757{
20763
20764 fMapDname=text;
20765}
20766
20767void NcAstrolab::MapMarkSize(const char* text)
20768{
20774
20775 TString s=text;
20776 fMapMarkSize=s.Atof();
20777}
20778
20780{
20786
20787 Int_t styles[17]={8,29,21,22,23,33,34,31,2,5,24,30,25,26,32,27,28};
20788
20789 if (i>17) return;
20790
20791 fMapMarkStyle=styles[i-1];
20792}
20793
20795{
20801
20802 Int_t colors[15]={kBlack,kRed,kBlue,kGreen,kYellow,kMagenta,kCyan,kOrange,kViolet,kPink,kAzure,kSpring,kTeal,kGray,kWhite};
20803
20804 if (i>15) return;
20805
20806 fMapMarkColor=colors[i-1];
20807}
20808
20810{
20816
20817 if (i<=4) fMapMarkType=i-1;
20818}
20819
20821{
20827
20828 if (i>10) return;
20829
20830 if (!fMapSolar[i-1])
20831 {
20832 fMapSolar[i-1]=1;
20833 }
20834 else
20835 {
20836 fMapSolar[i-1]=0;
20837 }
20838}
20839
20841{
20847
20848 TString names[10]={"Sun","Moon","Mercury","Venus","Earth","Mars","Jupiter","Saturn","Uranus","Neptune"};
20849
20850 SetMapTS(); // Get the selected timestamp
20851
20852 fSkyMapPanel->RequestFocus();
20853
20854 for (Int_t i=0; i<10; i++)
20855 {
20856 if (fMapSolar[i]) GetSignal(names[i],0,&fMapTS);
20857 }
20858 printf("\n *** Selected Solar system object(s) entered *** \n");
20859}
20860
20862{
20868
20869 TString names[10]={"Sun","Moon","Mercury","Venus","Earth","Mars","Jupiter","Saturn","Uranus","Neptune"};
20870
20871 SetMapTS(); // Get the selected timestamp
20872
20873 fSkyMapPanel->RequestFocus();
20874
20875 Int_t nrem=0;
20876 Int_t nremx=0;
20877 for (Int_t i=0; i<10; i++)
20878 {
20879 if (fMapSolar[i])
20880 {
20881 nremx=RemoveSignal(names[i],0,1);
20882 if (nremx) nrem++;
20883 }
20884 }
20885
20886 printf("\n *** Number of Solar system object that have been removed : %-i *** \n",nrem);
20887}
20888
20889void NcAstrolab::CommandPanel(TGCompositeFrame* frame)
20890{
20896
20897 if (!frame) return;
20898
20899 TGGroupFrame* panel=new TGGroupFrame(frame,"Commands",kVerticalFrame);
20900 panel->SetTitlePos(TGGroupFrame::kCenter);
20901 frame->AddFrame(panel);
20902
20903 TGTextButton* list=new TGTextButton(panel,"List");
20904 list->Connect("Clicked()","NcAstrolab",this,"MapList()");
20905 list->SetToolTipText("List the selected entries");
20906 TGLayoutHints* Llist=new TGLayoutHints(kLHintsCenterX,0,0,10,10);
20907 panel->AddFrame(list,Llist);
20908
20909 TGTextButton* map=new TGTextButton(panel,"Map");
20910 map->Connect("Clicked()","NcAstrolab",this,"MapDraw()");
20911 map->SetToolTipText("Display the selected entries");
20912 TGLayoutHints* Lmap=new TGLayoutHints(kLHintsCenterX,0,0,10,10);
20913 panel->AddFrame(map,Lmap);
20914
20915 TGTextButton* close=new TGTextButton(panel,"Close");
20916 close->Connect("Clicked()","NcAstrolab",this,"MapClose()");
20917 close->SetToolTipText("Close this panel window");
20918 TGLayoutHints* Lclose=new TGLayoutHints(kLHintsCenterX,0,0,10,10);
20919 panel->AddFrame(close,Lclose);
20920
20921 TGTextButton* exit=new TGTextButton(panel,"Exit");
20922 exit->Connect("Clicked()","NcAstrolab",this,"MapExit()");
20923 exit->SetToolTipText("Exit this ROOT session");
20924 TGLayoutHints* Lexit=new TGLayoutHints(kLHintsCenterX,0,0,10,10);
20925 panel->AddFrame(exit,Lexit);
20926}
20927
20929{
20935
20936 SetMapTS(); // Set the skymap timestamp
20937
20938 fSkyMapPanel->RequestFocus();
20939
20940 Int_t type=0;
20941 if (fMapDoptions[3]) type=1;
20942 if (fMapDoptions[2] && fMapDoptions[3]) type=-1;
20943
20944 NcTimestamp* ts=&fMapTS; // User selected timestamp
20945 if (fMapLabTS) ts=0; // To get Lab timestamp notification in listings
20946
20947 Int_t j=0;
20948 if (fMapDoptions[4]) j=-1; // Individual reference timestamps
20949
20950 printf("\n");
20952}
20953
20955{
20961
20962 SetMapTS(); // Set the skymap timestamp
20963
20964 fSkyMapPanel->RequestFocus();
20965
20966 Int_t type=0;
20967 if (fMapDoptions[3]) type=1;
20968 if (fMapDoptions[2] && fMapDoptions[3]) type=-1;
20969
20970 NcTimestamp* ts=&fMapTS; // User selected timestamp
20971 if (fMapLabTS) ts=0; // To get Lab timestamp notification in listings
20972
20973 Int_t j=0;
20974 if (fMapDoptions[4]) j=-1; // Individual reference timestamps
20975
20980
20982}
20983
20985{
20991
20992 // De-activate all automatic CloseWindow() actions of the system window manager
20993 // in order to fully control it in this function
20994 fSkyMapPanel->DontCallClose();
20995
20996 // To prevent crash when the cursor is still left active in a TextEntry
20997 fSkyMapPanel->RequestFocus();
20998
20999 // Unmap the display window
21000 fSkyMapPanel->UnmapWindow();
21001}
21002
21004{
21010
21011 fSkyMapPanel->RequestFocus();
21012 fSkyMapPanel->Cleanup();
21013 gApplication->Terminate(0);
21014}
21015
21017{
21023
21024 fMapLabTS=kFALSE;
21025 Int_t imjd=0;
21026 Int_t isec=0;
21027 Int_t ins=0;
21028 Int_t ips=0;
21029
21030 if (fMapTimeType=="SysClock") // Use the system clock time
21031 {
21032 fMapTS.SetSystemTime();
21033 }
21034 else if (fMapTimeType=="Lab") // Use the Lab timestamp
21035 {
21036 fMapTS.SetMJD(fMJD,fJsec,fJns,fJps);
21037 fMapLabTS=kTRUE;
21038 }
21039 else if (fMapTimeType=="MJD") // Modified Julian Date entry
21040 {
21041 Double_t mjd=fMapDateTime.Atof();
21042 fMapTS.SetMJD(mjd);
21043 }
21044 else if (fMapTimeType=="JD") // Julian Date entry
21045 {
21046 Double_t jd=fMapDateTime.Atof();
21047 fMapTS.SetJD(jd);
21048 }
21049 else if (fMapTimeType=="TJD") // Truncated Julian Date entry
21050 {
21051 Double_t tjd=fMapDateTime.Atof();
21052 fMapTS.SetTJD(tjd);
21053 }
21054 else if (fMapTimeType=="Unix") // Unix time
21055 {
21056 Double_t val=fMapDateTime.Atof();
21057 fMapTS.SetUnixTime(val);
21058 }
21059 else
21060 {
21061 if (fMapTimeType.Contains("Name")) // Get timestamp of the specified named entry
21062 {
21063 NcSignal* sx=0;
21064 NcTimestamp* tx=0;
21065 TString name=fMapDateTime;
21066 sx=GetSignal(name,1);
21067 if (!sx) sx=GetSignal(name,0);
21068 if (sx) tx=sx->GetTimestamp();
21069 if (tx) // Stored entry was found
21070 {
21071 tx->GetMJD(imjd,isec,ins);
21072 ips=tx->GetPs();
21073 fMapTS.SetMJD(imjd,isec,ins,ips);
21074 }
21075 else
21076 {
21077 printf("\n *** No stored entry with name %-s found --> Lab TS will be used *** \n",name.Data());
21078 GetMJD(imjd,isec,ins);
21079 ips=GetPs();
21080 fMapTS.SetMJD(imjd,isec,ins,ips);
21081 fMapLabTS=kTRUE;
21082 }
21083 fMapTS.GetDayTimeString("UTC",12,0,&fMapDate,&fMapTime,kFALSE);
21084 }
21085 else // Date/Time entry
21086 {
21088 fMapDate.Remove(fMapDateTime.Index("/"),fMapDateTime.Length());
21090 fMapTime.Remove(0,fMapDateTime.Index("/")+1);
21091 }
21092
21093 // Set the timestamp according to the date/time strings
21094 fMapTS.SetUT(fMapDate,fMapTime,0);
21095 if (fMapTimeType=="UT1") fMapTS.SetUT(fMapDate,fMapTime,0,"U");
21096 if (fMapTimeType=="LMT") fMapTS.SetLT(fToffset,fMapDate,fMapTime,0);
21097 if (fMapTimeType=="GPS" || fMapTimeType=="TAI" || fMapTimeType=="TT")
21098 {
21099 fMapTS.SetTAI(fMapTimeType,fMapDate,fMapTime,0,"A",0);
21100 }
21101 }
21102
21103 // Show the new timestamp in the textbox
21104 fMapTS.GetDayTimeString("UTC",3,0,&fMapDate,&fMapTime,kFALSE);
21106 fMapDateTime+="/";
21108 fMapTSdatetime->SetText(fMapDateTime);
21109
21110 // Adapt the timestamp type for the updated text window contents
21111 if (fMapTStimetype) fMapTStimetype->Select(1,kTRUE);
21112 MapTimeType(1);
21113}
21114
21115TObject* NcAstrolab::Clone(const char* name) const
21116{
21125
21126 NcAstrolab* lab=new NcAstrolab(*this);
21127 if (name)
21128 {
21129 if (strlen(name)) lab->SetName(name);
21130 }
21131 return lab;
21132}
21133
ClassImp(NcAstrolab)
Handling of 3-vectors in various reference frames.
Definition Nc3Vector.h:15
Double_t GetX(Int_t i, TString f, TString u="rad")
void GetErrors(Double_t *e, TString f, TString u="rad") const
void SetVector(Double_t *v, TString f, TString u="rad")
virtual void Load(Nc3Vector &q)
virtual void SetZero()
Nc3Vector Cross(Nc3Vector &q) const
void SetErrors(Double_t *e, TString f, TString u="rad")
virtual Double_t GetOpeningAngle(Nc3Vector &q, TString u="rad")
void GetVector(Double_t *v, TString f, TString u="rad") const
Int_t HasErrors() const
Nc3Vector GetPrimed(TRotMatrix *m) const
Int_t HasVector() const
Nc3Vector GetUnprimed(TRotMatrix *m) const
Double_t GetNorm()
Virtual lab to provide (astro)physical parameters, treat data and relate observations with astrophysi...
Definition NcAstrolab.h:47
Double_t fMW
Definition NcAstrolab.h:376
void MapMerUc(Int_t i)
void Precess(Nc3Vector &r, NcTimestamp *ts1, NcTimestamp *ts2)
void MapEname(const char *text)
void Nutate(Nc3Vector &r, NcTimestamp *ts)
void MakeBurstRecoAngresdist(TString file, TString tree, TString name1, TString name2, TString ua, TString name3, TString ud, Double_t Emin, Double_t Emax, Int_t nbe=100, Int_t nba=1000)
Double_t fMapMerC
! The GUI entered central meridian location for the Map
Definition NcAstrolab.h:360
void ProjectMercator(Double_t l, Double_t b, Double_t &x, Double_t &y)
Double_t fMeridian
! Central meridian (in rad) for the sky display
Definition NcAstrolab.h:306
void MakeBurstDataStats()
Double_t GetTargetThickness(Double_t prob, Double_t lambda) const
Double_t fMp
Definition NcAstrolab.h:374
TRotMatrix fL
Definition NcAstrolab.h:270
virtual void LabLocationPanel(TGCompositeFrame *frame)
void GetBurstBayesianPsiStatistics(TString type, Double_t nr=-1, Int_t ncut=10, Int_t ndt=2, Bool_t zcor=kFALSE, Int_t freq=0)
void MapEnterSolar()
Double_t GetCredibleInterval(TF1 pdf, Double_t p, Double_t &xlow, Double_t &xup, Int_t n=1000)
void SetRandomiser(Int_t iseed, Int_t cnt1=0, Int_t cnt2=0, NcTimestamp *ts=0)
Double_t GetLT()
Double_t GetUpperLimit(TF1 pdf, Double_t p)
Double_t fGammaW
Definition NcAstrolab.h:377
Double_t fSpeedC
Definition NcAstrolab.h:368
TH1F GetDxHistogram(TH1 *hx, Int_t nc, Double_t dxbin=-1, Double_t dxmin=-1, Double_t dxmax=-1, Int_t mode=1, Double_t fact=1)
TString fDataFrame
Definition NcAstrolab.h:409
ULong64_t fNen[2]
Definition NcAstrolab.h:261
NcSample fBurstOffAeff
Definition NcAstrolab.h:429
Double_t fMapMarkSize
! The GUI entered marker size for the Map
Definition NcAstrolab.h:362
TF1 * fPhiscfunc
Definition NcAstrolab.h:285
void HelioToGeocentric(Double_t &R, Double_t &B, Double_t &L, NcTimestamp *ts, TString Bu="deg", TString Lu="deg")
void MapMarkType(Int_t i)
Int_t GetTimeScramble(Double_t *tmin=0, Double_t *tmax=0, TF1 *frndm=0)
TRotMatrix fP
! Matrix for precession correction
Definition NcAstrolab.h:264
Double_t fHbarc2
Definition NcAstrolab.h:398
Double_t fTscmin
Definition NcAstrolab.h:273
void MapCinfo(Int_t)
void MapEb(const char *text)
Double_t fAlphaEM
Definition NcAstrolab.h:380
void MatchSignals(NcDevice &matches, Double_t da, TString au, Double_t dt, TString tu, Int_t mode=1, Int_t i1=1, Int_t i2=0, Int_t itype=0, Int_t j1=1, Int_t j2=0, Int_t jtype=1)
TF1 fBkgEprofile
Definition NcAstrolab.h:417
TString fMapEcoord
! The GUI entered coordinate system of the entry
Definition NcAstrolab.h:348
Int_t SetSolarSystem(TString name, NcTimestamp *ts, Int_t type=0)
Double_t GetLightTravelDistance(Double_t z, TString u="Mpc") const
Double_t fMapLabLocB
! The GUI entered Lab latitude
Definition NcAstrolab.h:326
Double_t fToffset
Definition NcAstrolab.h:257
TString fMapEua
! The GUI entered angular units of a
Definition NcAstrolab.h:344
Double_t fOmegaR
Definition NcAstrolab.h:390
Double_t fThetascmin
Definition NcAstrolab.h:280
Double_t fAmu
Definition NcAstrolab.h:373
Int_t fSolUpdate
Definition NcAstrolab.h:301
void SetBurstParameter(TString name, Double_t value)
void InitBurstHistograms()
void MapProj(Int_t i)
TString fBkgEmode
Definition NcAstrolab.h:415
TObjArray * fSigs
Definition NcAstrolab.h:260
Double_t fDscmin
Definition NcAstrolab.h:277
NcObjMatrix fDataNames
Definition NcAstrolab.h:411
void SmearPosition(Nc3Vector &v, Double_t sigma)
Double_t GetLightTravelTime(Double_t z) const
Int_t GetPositionScramble(Double_t *dmin=0, Double_t *dmax=0, TF1 *df=0, Double_t *thmin=0, Double_t *thmax=0, TF1 *thf=0, Double_t *phimin=0, Double_t *phimax=0, TF1 *phif=0)
void ProjectCylindrical(Double_t l, Double_t b, Double_t &x, Double_t &y)
void MapExperiment(Int_t i)
void MapMarkSize(const char *text)
TRotMatrix fG
! Matrix for conversion of equatorial to galactic coordinates
Definition NcAstrolab.h:266
Float_t fMarkerSize[4]
Definition NcAstrolab.h:311
NcSample GetBurstDataSample(TString type, TString data) const
TString fMapTime
! The GUI entered time
Definition NcAstrolab.h:333
Double_t GetBurstRecoAngres(Double_t Emin=-1, Double_t Emax=-1, Double_t Amin=0, Double_t Amax=999) const
TString fExperiment
Definition NcAstrolab.h:255
TRotMatrix fB
! The frame bias matrix for conversion of ICRS to J2000 coordinates
Definition NcAstrolab.h:262
virtual void EntriesPanel(TGCompositeFrame *frame)
TH1 * GetBurstBayesianSignalRate(Double_t p, Double_t &rlow, Double_t &rup, Int_t n=1000)
Double_t ConvertAngle(Double_t a, TString in, TString out) const
TObjArray fBurstHistos
Definition NcAstrolab.h:421
void SetNmatrix(NcTimestamp *ts)
Double_t fGn
Definition NcAstrolab.h:385
Double_t fOmegaC
Definition NcAstrolab.h:393
Double_t fHbar
Definition NcAstrolab.h:396
void ProjectHammer(Double_t l, Double_t b, Double_t &x, Double_t &y)
Double_t GetDifference(Int_t jref, TString au, Double_t &dt, TString tu, Int_t mode=1, Int_t *ia=0, Int_t *it=0)
void ListSignals(TString frame, TString mode, Int_t ndig=1, TString emode="T", Int_t nmax=10, Int_t j=-1, Int_t type=-1, NcTimestamp *ts=0, TString name="*")
Double_t GetSourceAttributes(NcSignal *s, Float_t *z=0, Float_t *T90=0)
NcPosition fLabPos
Definition NcAstrolab.h:254
TString fProj
! Projection which is currently in use
Definition NcAstrolab.h:307
Double_t GetLuminosityDistance(Double_t z, TString u="Mpc") const
NcDevice * fBurstParameters
Definition NcAstrolab.h:420
TRotMatrix fH
! Matrix for conversion of equatorial to horizontal coordinates
Definition NcAstrolab.h:269
Int_t RemoveSignal(Int_t j, Int_t type, Int_t compress)
Double_t GetBurstBackgroundEnergy(Double_t Emin=-1, Double_t Emax=-1) const
void SetLabPosition(Nc3Vector &r)
void MapLabLframeEnter()
TString fMapTimeType
! The GUI entered time type
Definition NcAstrolab.h:334
TString GetExperiment() const
void MapDoptions(Int_t i)
Double_t GetLabTimeOffset() const
void GenBurstGCNdata(Int_t n, TString name="GRB", Bool_t scale=kFALSE)
Double_t GetComovingDistance(Double_t z, TString u="Mpc") const
Double_t fNewton
Definition NcAstrolab.h:384
TH2 * fHist[2]
! Temp. histograms for the sky display
Definition NcAstrolab.h:309
TGComboBox * fMapTStimetype
! The GUI TS time type selection box
Definition NcAstrolab.h:331
TString fMapCinfo
! The GUI selected info category
Definition NcAstrolab.h:339
Double_t fTscmax
Definition NcAstrolab.h:274
void MapMerMode(Int_t i)
TArrayI * fIndices
! Storage indices of the matching reference signals
Definition NcAstrolab.h:271
TH1 * GetBurstSigmaPosdist(TString name, TString type)
TString fMapProj
! The GUI selected projection for the Map
Definition NcAstrolab.h:352
Bool_t fMapLabTS
! The GUI selection to use the Lab timestamp for the List/Map
Definition NcAstrolab.h:337
void MapEcoord(Int_t i)
void GetLocalFrame(Float_t arr[6])
void LoadInputData(Bool_t src, TString file, TString tree, Int_t date1=0, Int_t date2=0, Int_t nmax=-1, TString type="-")
NcSample fBurstSigReco
Definition NcAstrolab.h:424
Double_t fGammaZ
Definition NcAstrolab.h:379
NcSample fBurstOnReco
Definition NcAstrolab.h:422
TF1 * fThetascfunc
Definition NcAstrolab.h:282
TString fMapLabLocU
! The GUI entered Lab location angular units
Definition NcAstrolab.h:327
TCanvas * fCanvas
! The canvas for the skymap
Definition NcAstrolab.h:308
Double_t fOmegaM
Definition NcAstrolab.h:389
TF1 fSigEprofile
Definition NcAstrolab.h:416
void MapDname(const char *text)
void MapIname(const char *text)
NcAstrolab(const char *name="User", const char *title="Virtual Lab for general use")
Double_t GetBurstLiMaSignificance() const
virtual void SkyMapPanel()
Int_t GetSignalIndex(TString name, Int_t type=0)
TGTextEntry * fMapTSdatetime
! The GUI TS date/time specification
Definition NcAstrolab.h:330
void MapLocb(const char *text)
TRotMatrix fN
! Matrix for nutation correction
Definition NcAstrolab.h:265
void ListBurstParameters() const
TGNumberEntryField * fMapLabLBI[3]
! The GUI number entries for the Lab location specification
Definition NcAstrolab.h:322
void MapTinfo(Int_t)
void MapEa(const char *text)
void ListBurstDataStats() const
Double_t GetMeanFreePath(Double_t sigma, Double_t rho, Int_t mode) const
NcPosition GetLabPosition() const
void SetPositionScramble(Int_t mode, Double_t dmin, Double_t dmax, TF1 *df=0, Double_t thmin=0, Double_t thmax=0, TF1 *thf=0, Double_t phimin=0, Double_t phimax=0, TF1 *phif=0)
void InitDataNames(Int_t dir, TString frame, TString mode="J")
Double_t GetHubbleParameter(Double_t z, TString u="Mpc") const
void MapEtype(Int_t i)
void LoadAeffData(TString file, TString hist)
Int_t fMapMarkStyle
! The GUI selected marker style for the Map
Definition NcAstrolab.h:363
Int_t SetSourceAttributes(NcSignal *s, Double_t sigmapos, TString u, Double_t z=-999, Double_t T90=-999)
void MapUa(Int_t i)
Double_t GetMaxDt() const
void SetTimeScramble(Int_t mode, Double_t tmin, Double_t tmax, TF1 *frndm=0)
TString fMapDcoord
! The GUI selected coordinate system for the Map/List
Definition NcAstrolab.h:351
void MapUinfo(Int_t)
void MapDcoord(Int_t i)
Double_t fPhiscmin
Definition NcAstrolab.h:283
Double_t fPhiscmax
Definition NcAstrolab.h:284
void SetPmatrix(NcTimestamp *ts)
void MakeBurstNuCountProfile(TString mode)
Double_t GetLAST()
Double_t fMapEb
! The GUI entered b coordinate of an entry
Definition NcAstrolab.h:345
TString fMapDate
! The GUI entered date
Definition NcAstrolab.h:332
TF1 GetSignalRatePDF(Double_t Non, Double_t Ton, Double_t Noff, Double_t Toff, Double_t Ra=1, Double_t Re=1, Double_t smax=-1, Double_t bmax=-1, Double_t prec=709)
Double_t fDscmax
Definition NcAstrolab.h:278
Double_t fMapLabLocL
! The GUI entered Lab longitude
Definition NcAstrolab.h:325
Int_t fMapMarkType
! The GUI selected entry type to apply the marker attributes on
Definition NcAstrolab.h:365
void MapMarkStyle(Int_t i)
Double_t fPc
Definition NcAstrolab.h:387
Double_t fMn
Definition NcAstrolab.h:375
void Project(Double_t l, Double_t b, TString proj, Double_t &x, Double_t &y)
TH1 * GetBurstHistogram(TString name) const
Double_t fQe
Definition NcAstrolab.h:369
void MapUloc(Int_t i)
void SetBmatrix()
NcRandom * fRan
Definition NcAstrolab.h:286
void MapDateTime(const char *text)
Double_t GetBurstTotalFluence(Double_t nsig, TString str)
Double_t fThetascmax
Definition NcAstrolab.h:281
TString fMapDmode
! The GUI selected coordinate system mode for the Map/List
Definition NcAstrolab.h:353
Double_t GetShieldingThickness(Double_t prob, Double_t lambda) const
TString fMapEub
! The GUI entered angular units of b
Definition NcAstrolab.h:346
void MapMarkColor(Int_t i)
Double_t GetBackgroundRateProb(Double_t *vars, Double_t *pars)
Double_t GetInteractionProbability(Double_t x, Double_t lambda) const
void MakeBurstSigmaPosdist(TString file, TString tree, TString name, TString u, Int_t nb=900, Float_t xmin=0, Float_t xmax=90)
void MapNdigs(const char *text)
Int_t GetNRefSignals(Int_t mode=0) const
TH1F GetDifHistogram(TH1 *hin, Int_t mode, TString s="", TF1 *f=0) const
Int_t fMapEtype
! The GUI entered entry type
Definition NcAstrolab.h:347
TGComboBox * fMapLabU
! The GUI Lab location angular unit selection box
Definition NcAstrolab.h:323
Double_t fAu
Definition NcAstrolab.h:386
NcSample fBurstOffMatch
Definition NcAstrolab.h:427
void MapLocEnter()
void SetDataNames(TString obsname, TString varname, TString units="1", TString func="none")
TString fMapDname
! The GUI entered name pattern for entries to be shown in the Map/List
Definition NcAstrolab.h:357
TGNumberEntryField * fMapLabLframe[6]
! The GUI number entries for the local frame specification
Definition NcAstrolab.h:338
Double_t fOmegaL
Definition NcAstrolab.h:391
void GenBurstSignals()
void SetGmatrix(TString mode)
Double_t GetNeutrinoXsection(Int_t mode, Int_t type, Double_t egev, Double_t xscale=1, Double_t *eprimgev=0, Double_t *alpha=0) const
TH1 * GetBurstT90dist(TString name, TString type)
Double_t fMe
Definition NcAstrolab.h:370
NcDevice * GetBurstParameters()
void ListBurstHistograms() const
void MakeBurstEnergydist(Int_t mode, TString file, TString tree, TString name1, TString name2, TString u, Int_t nb=1000)
void SetLT(Int_t y, Int_t m, Int_t d, Int_t hh, Int_t mm, Int_t ss, Int_t ns=0, Int_t ps=0)
void MapSolar(Int_t i)
void MapLocl(const char *text)
Int_t fLabId
Definition NcAstrolab.h:256
void SetCentralMeridian(Int_t mode=0, Double_t phi=0, TString u="deg")
Int_t fGal
! Type indicator for fG values (0=uninitialised 1=B1950 2=J2000)
Definition NcAstrolab.h:267
NcSample fBurstSignal
Definition NcAstrolab.h:425
Int_t fMapLabId
! The GUI entered Lab detector Id
Definition NcAstrolab.h:329
void ListBurstSignalStats(Double_t rate, Int_t mode, TString str="-")
void SetEmatrix(NcTimestamp *ts)
Int_t RemoveRefSignal(Int_t j, Int_t compress)
Int_t fMapMarkColor
! The GUI selected marker color for the Map
Definition NcAstrolab.h:364
void MakeBurstT90dist(TString file, TString tree, TString name, Int_t nb=50, Float_t xmin=-5, Float_t xmax=5)
void MapRemoveSolar()
void MapUb(Int_t i)
void DisplaySignal(TString frame, TString mode, NcTimestamp *ts, Int_t j=-1, TString proj="ham", Int_t clr=0, TString name="")
virtual void TimestampPanel(TGCompositeFrame *frame)
void SetHmatrix(NcTimestamp *ts)
void PrintSignal(TString frame, TString mode, NcTimestamp *ts, Int_t ndig, Int_t jref=0, TString emode="T", Int_t type=0, Bool_t align=kFALSE)
void SetLabTimeOffset(Double_t dt)
TH1F GetCumulHistogram(TH1 *h, TString name, TString mode="F") const
virtual void MapListOptionsPanel(TGCompositeFrame *frame)
TObjArray * fMarkers
! Temp. array to hold the markers for the signal display
Definition NcAstrolab.h:310
TString fMapDateTime
! The GUI entered datetime
Definition NcAstrolab.h:335
Double_t GetSolidAngle(Double_t thetamin, Double_t thetamax, TString tu, Double_t phimin, Double_t phimax, TString pu) const
void SetMarkerColor(Int_t color, Int_t type)
Int_t fMapNdigs
! The GUI selected number of digits for the List output
Definition NcAstrolab.h:356
TRotMatrix fE
! Matrix for conversion of equatorial to ecliptic coordinates
Definition NcAstrolab.h:268
Double_t GetProperDistance(Double_t z, TString u="Mpc", Int_t t=1) const
TString fMapIname
! The GUI selected entry name for the info
Definition NcAstrolab.h:342
Double_t fMapEa
! The GUI entered a coordinate of an entry
Definition NcAstrolab.h:343
Double_t fFermi
Definition NcAstrolab.h:381
Double_t fAxes[6]
Definition NcAstrolab.h:258
Bool_t fMapSolar[10]
! The GUI selection of solar system objects
Definition NcAstrolab.h:358
TF1 * fTscfunc
Definition NcAstrolab.h:275
void GetBurstChi2Statistics(TString type, Int_t ndt=2, Bool_t zcor=kFALSE)
Double_t GetBurstSignalEnergy(Double_t Emin=-1, Double_t Emax=-1) const
void MapLocId(const char *text)
Bool_t fMapDoptions[5]
! The GUI Map/List options (histo, clr, ref, meas, refTS)
Definition NcAstrolab.h:354
Int_t fRscmode
Definition NcAstrolab.h:276
Int_t RemoveSignals(TString name, Int_t type, Int_t compress)
void SetPhysicalParameter(TString name, Double_t value)
Double_t fHubble
Definition NcAstrolab.h:388
Double_t fMmu
Definition NcAstrolab.h:371
void MatchBurstData(NcDevice &matches, Int_t i1=1, Int_t i2=0, Int_t itype=0, Int_t j1=1, Int_t j2=0, Int_t jtype=1)
void ShiftPosition(Nc3Vector &v, Double_t angle)
void MakeBurstZdist(TString file, TString tree, TString name, Int_t nb=200, Float_t zmin=0, Float_t zmax=20)
TString fDataMode
Definition NcAstrolab.h:410
TArrayI * MatchRefSignal(Double_t da, TString au, Double_t dt, TString tu, Int_t mode=1)
NcSample fBurstSigAeff
Definition NcAstrolab.h:430
void WriteBurstHistograms(TString filename)
void GeoToHeliocentric(Double_t &R, Double_t &B, Double_t &L, NcTimestamp *ts, TString Bu="deg", TString Lu="deg")
Double_t GetSignalRateProb(Double_t *vars, Double_t *pars)
Double_t GetNuclearMass(Int_t Z, Int_t N, Int_t mode=1) const
Int_t fTscmode
Definition NcAstrolab.h:272
virtual void InfoPanel(TGCompositeFrame *frame)
void BurstCompensate(Int_t &nmugrb)
void SetLocalFrame(Double_t t1, Double_t p1, Double_t t2, Double_t p2, Double_t t3, Double_t p3)
void Data(Int_t mode=1, TString u="deg", Bool_t utc=kTRUE)
void ProjectAitoff(Double_t l, Double_t b, Double_t &x, Double_t &y)
void SetMarkerSize(Float_t size, Int_t type)
TF1 * fDscfunc
Definition NcAstrolab.h:279
void DisplaySignals(TString frame, TString mode, NcTimestamp *ts, TString proj="ham", Int_t clr=0, Int_t nmax=-1, Int_t j=-1, Int_t type=-1, TString name="*")
NcSignal * GetSignal(Double_t &d, Double_t &a, TString au, Double_t &b, TString bu, TString frame, NcTimestamp *ts, Int_t jref, TString mode="T", Int_t type=0)
void ListDataNames()
virtual void LabLocalFramePanel(TGCompositeFrame *frame)
TString fMapMerUc
! The GUI selected angular units for the central meridian location
Definition NcAstrolab.h:361
NcSample fBurstOffReco
Definition NcAstrolab.h:426
TF1 * fNuAngle
Definition NcAstrolab.h:401
Int_t fMarkerStyle[4]
Definition NcAstrolab.h:312
Int_t fUsMeridian
Definition NcAstrolab.h:305
void SetExperiment(TString name, Int_t id=0)
TH1 * GetBurstZdist(TString name, TString type)
TString fMapUinfo
! The GUI selected angular units for the Lab info
Definition NcAstrolab.h:341
Double_t fMaxDt
Definition NcAstrolab.h:287
TString fMapEname
! The GUI entered name of the entry
Definition NcAstrolab.h:350
Int_t GetLabDetectorId() const
Double_t fMtau
Definition NcAstrolab.h:372
Double_t GetPhysicalParameter(TString name) const
virtual TObject * Clone(const char *name="") const
Double_t GetNeutrinoAngle(Double_t E, TString u, Int_t mode, TF1 *f=0)
Double_t fOmegaB
Definition NcAstrolab.h:392
TGMainFrame * fSkyMapPanel
! The main frame for the SkyMapPanel GUI
Definition NcAstrolab.h:321
Int_t GetNsignals(Int_t type, Int_t mode=0) const
Double_t fPlanck
Definition NcAstrolab.h:382
Double_t fBoltz
Definition NcAstrolab.h:383
void SetMarkerStyle(Int_t style, Int_t type)
NcSignal * SetSignal(Double_t d, Double_t a, TString au, Double_t b, TString bu, TString frame, NcTimestamp *ts, Int_t jref, TString mode="T", TString name="", Int_t type=0)
Int_t fDataDir
Definition NcAstrolab.h:408
Double_t GetLMST()
Int_t fMapMerMode
! The GUI selected meridian orientation for the Map
Definition NcAstrolab.h:359
void PrintAngle(Double_t a, TString in, TString out, Int_t ndig=1, Bool_t align=kFALSE) const
Int_t fMarkerColor[4]
Definition NcAstrolab.h:313
void MapMerC(const char *text)
Int_t fMapTinfo
! The GUI selected mode for the timestamp info
Definition NcAstrolab.h:340
void SetMaxDt(Double_t s)
TH1F GetLogHistogram(TH1 *hin, Int_t mode, TString s="") const
NcTimestamp fMapTS
! The GUI entered timestamp to be used for the List/Map
Definition NcAstrolab.h:336
Double_t GetPhysicalDistance(Double_t z, TString u="Mpc", Int_t t=1) const
void MapTimeType(Int_t i)
Double_t KolmogorovTest(TString mode, TH1 *h1, TH1 *h2=0, TF1 *pdf=0, Double_t nr=1000, TH1F *ksh=0, Int_t ncut=0, Double_t *nrx=0, Int_t mark=1)
TGComboBox * fMapLabE
! The GUI Lab experiment site selection box
Definition NcAstrolab.h:324
virtual void CommandPanel(TGCompositeFrame *frame)
Double_t GetSurvivalProbability(Double_t x, Double_t lambda) const
NcSample fBurstOnAeff
Definition NcAstrolab.h:428
Double_t GetHourAngle(TString mode, NcTimestamp *ts, Int_t jref=0, Int_t type=0)
Double_t GetRadiationLength(Double_t Z, Double_t A, Double_t rho=-1) const
Int_t fMapNmax
! The GUI selected max. number of signals of each type to Map/List
Definition NcAstrolab.h:355
Int_t fBias
! Initialisation flag for fB values (0=uninitialised 1=initialised)
Definition NcAstrolab.h:263
void RandomPosition(Nc3Vector &v, Double_t thetamin, Double_t thetamax, Double_t phimin, Double_t phimax)
TObjArray * fRefs
Definition NcAstrolab.h:259
TString fMapLabExpName
! The GUI entered Lab experimental site
Definition NcAstrolab.h:328
TF1 GetBackgroundRatePDF(Double_t Noff, Double_t Toff, Double_t bmax=-1, Double_t prec=709)
TString fMapEmode
! The GUI entered coordinate system mode of the entry
Definition NcAstrolab.h:349
NcRandom * GetRandomiser(Int_t &iseed, Int_t &cnt1, Int_t &cnt2) const
void GetBurstDtDistributions(Int_t ndt, TH1F &hisdtOn, TF1 &pdfdtOn, TH1F &hisdtOff, TF1 &pdfdtOff, Bool_t zcor)
Double_t GetBurstParameter(TString name)
void MapNmax(const char *text)
Double_t fMZ
Definition NcAstrolab.h:378
TH1F GetCountsHistogram(TF1 &spec, Int_t nbins, Double_t xmin, Double_t xmax, Int_t mode, TString s="") const
virtual ~NcAstrolab()
NcSample fBurstOnMatch
Definition NcAstrolab.h:423
Double_t fHbarc
Definition NcAstrolab.h:397
TString fSigEmode
Definition NcAstrolab.h:414
Double_t GetSeparation(TString name1, TString name2, TString au, Double_t *dt=0, TString tu="s", Int_t mode=1, Double_t *diftheta=0, Double_t *difphi=0)
void AddNamedSlot(TString s)
Int_t GetSlotIndex(TString name, Int_t opt=0) const
(Bayesian) Block treatment of sequential data.
Definition NcBlocks.h:17
Int_t Rebin(TH1 *hin, TH1 *hout, Bool_t scale, Int_t nbins=0, Double_t xmin=0, Double_t xmax=-1)
Int_t Divide(TH1 *h1, TH1 *h2, TH1 *hout, Bool_t scale, Double_t c, Double_t d=0)
Double_t GetBlocks(TH1 *hin, Double_t fpr, TH1 *hout, Int_t ntrig=0)
Definition NcBlocks.cxx:523
Signal (Hit) handling of a generic device.
Definition NcDevice.h:14
void AddHit(NcSignal &s)
Definition NcDevice.cxx:336
void SetHitCopy(Int_t j)
Definition NcDevice.cxx:237
virtual TObject * Clone(const char *name="") const
Int_t GetNhits() const
Definition NcDevice.cxx:437
NcSignal * GetHit(Int_t j) const
Definition NcDevice.cxx:489
virtual void Reset(Int_t mode=0)
Definition NcDevice.cxx:222
Various mathematical tools for scientific analysis.
Definition NcMath.h:26
Double_t PsiValue(Int_t m, Int_t *n, Double_t *p=0, Int_t f=0) const
Definition NcMath.cxx:2829
Double_t LnGamma(Double_t z) const
Definition NcMath.cxx:193
Double_t Chi2Pvalue(Double_t chi2, Int_t ndf, Int_t sides=0, Int_t sigma=0, Int_t mode=1) const
Definition NcMath.cxx:1784
Double_t LiMaSignificance(Double_t Non, Double_t Ton, Double_t Noff, Double_t Toff, Double_t Ra=1, Double_t Re=1) const
Definition NcMath.cxx:4172
Double_t Gamma(Double_t z) const
Definition NcMath.cxx:121
Double_t PsiExtreme(Double_t n, Int_t m, Double_t *p=0, Int_t k=0) const
Definition NcMath.cxx:3138
Double_t PsiPvalue(Double_t psi0, Double_t nr, Double_t n, Int_t m, Double_t *p=0, Int_t f=0, Double_t *na=0, TH1F *psih=0, Int_t ncut=0, Double_t *nrx=0, Int_t mark=1)
Definition NcMath.cxx:3528
TF1 PoissonDtDist(Double_t r, Int_t n) const
Definition NcMath.cxx:1260
Double_t Chi2Value(Int_t m, Int_t *n, Double_t *p=0, Int_t *ndf=0) const
Definition NcMath.cxx:3867
Handling of positions (with timestamps) in various reference frames.
Definition NcPosition.h:18
void GetPosition(Double_t *r, TString f, TString u="rad", Float_t s=-1) const
void SetPosition(Double_t *r, TString f, TString u="rad")
NcTimestamp * GetTimestamp()
void SetTimestamp(NcTimestamp &t)
Generate universal random numbers and sequences on all common machines.
Definition NcRandom.h:16
Sampling and statistics tools for various multi-dimensional data samples.
Definition NcSample.h:28
Int_t GetN() const
Double_t GetMedian(Int_t i)
void Enter(Double_t x)
Definition NcSample.cxx:357
void SetStoreMode(Int_t mode=1, Int_t nmax=0, Int_t i=0)
Double_t GetEntry(Int_t i, Int_t j, Int_t mode=0, Int_t k=0)
Generic handling of (extrapolated) detector signals.
Definition NcSignal.h:23
virtual void Reset(Int_t mode=0)
Definition NcSignal.cxx:334
virtual void SetSignal(Double_t sig, Int_t j=1)
Definition NcSignal.cxx:516
virtual Float_t GetSignal(Int_t j=1, Int_t mode=0) const
Definition NcSignal.cxx:651
virtual void Data(TString f="car", TString u="rad") const
Definition NcSignal.cxx:959
Double_t GetEpoch(TString mode)
Double_t GetMJD(Int_t y, Int_t m, Int_t d, Int_t hh, Int_t mm, Int_t ss, Int_t ns) const
void SetLT(Double_t dt, Int_t y, Int_t m, Int_t d, Int_t hh, Int_t mm, Int_t ss, Int_t ns=0, Int_t ps=0, TString utc="A", Int_t leap=0, Double_t dut=0)
Double_t GetJD(Int_t y, Int_t m, Int_t d, Int_t hh, Int_t mm, Int_t ss, Int_t ns) const
void GetUT(Int_t &hh, Int_t &mm, Int_t &ss, Int_t &ns, Int_t &ps)
TString GetDayTimeString(TString mode, Int_t ndig=0, Double_t offset=0, TString *date=0, TString *time=0, Bool_t full=kTRUE)
Double_t Almanac(Double_t *dpsi=0, Double_t *deps=0, Double_t *eps=0, Double_t *dl=0, TString name="", Double_t *el=0, Double_t *eb=0, Double_t *dr=0, Double_t *value=0, Int_t j=0)
Double_t GetLMST(Double_t offset)
Double_t GetMJD()
Int_t GetPs() const
Double_t GetLT(Double_t offset)
void GetGMST(Int_t &hh, Int_t &mm, Int_t &ss, Int_t &ns, Int_t &ps)
void SetEpoch(Double_t e, TString mode, TString utc="U", Int_t leap=0, Double_t dut=0)
Double_t GetGAST()
void SetUT(Int_t y, Int_t m, Int_t d, Int_t hh, Int_t mm, Int_t ss, Int_t ns=0, Int_t ps=0, TString utc="A", Int_t leap=0, Double_t dut=0)
void PrintTime(Double_t h, Int_t ndig=1) const
Double_t GetLAST(Double_t offset)
TTree * LoadUTCparameterFiles(TString leapfile="$(NCFS)/IERS/leap.txt", TString dutfile="$(NCFS)/IERS/dut.txt")
void SetTJD(Int_t tjd, Int_t sec, Int_t ns, Int_t ps=0, TString utc="U", Int_t leap=0, Double_t dut=0)
void SetMJD(Int_t mjd, Int_t sec, Int_t ns, Int_t ps=0, TString utc="U", Int_t leap=0, Double_t dut=0)
void SetJD(Int_t jd, Int_t sec, Int_t ns, Int_t ps=0, TString utc="U", Int_t leap=0, Double_t dut=0)
Double_t GetUnixTime()
void Add(Int_t d, Int_t s, Int_t ns, Int_t ps=0)
void Convert(Double_t date, Int_t &days, Int_t &secs, Int_t &ns) const
Int_t GetDifference(NcTimestamp *t, Int_t &days, Int_t &sec, Int_t &ns, Int_t &ps, TString type="UT")
void AddSec(Double_t seconds)
void Date(Int_t mode=3, Double_t offset=0)