diff --git a/Utilities/DataHelper/CMakeLists.txt b/Utilities/DataHelper/CMakeLists.txt index 3d1e61224c731b39cc3527efa526078ba36a7e9c..a0b346f3580fbbf1567c01dda9710193118d43a0 100644 --- a/Utilities/DataHelper/CMakeLists.txt +++ b/Utilities/DataHelper/CMakeLists.txt @@ -1,10 +1,11 @@ gaudi_subdir(DataHelper v0r0) find_package(EDM4HEP REQUIRED) -set (gsl_include "/cvmfs/cepc.ihep.ac.cn/software/cepcsoft/x86_64-sl6-gcc49/external/GSL/1.14/install/include") -set (gsl_lib1 "/cvmfs/cepc.ihep.ac.cn/software/cepcsoft/x86_64-sl6-gcc49/external/GSL/1.14/install/lib/libgsl.so") -set (gsl_lib2 "/cvmfs/cepc.ihep.ac.cn/software/cepcsoft/x86_64-sl6-gcc49/external/GSL/1.14/install/lib/libgslcblas.so") -INCLUDE_DIRECTORIES(${gsl_include}) +find_package(GSL REQUIRED ) +message("GSL: ${GSL_LIBRARIES} ") +message("GSL INCLUDE_DIRS: ${GSL_INCLUDE_DIRS} ") + +INCLUDE_DIRECTORIES(${GSL_INCLUDE_DIRS}) gaudi_depends_on_subdirs() @@ -14,5 +15,5 @@ set(DataHelperLib_srcs src/*.cc src/*.cpp) gaudi_add_library(DataHelperLib ${DataHelperLib_srcs} PUBLIC_HEADERS DataHelper - LINK_LIBRARIES EDM4HEP::edm4hep EDM4HEP::edm4hepDict ${gsl_lib1} ${gsl_lib2} + LINK_LIBRARIES EDM4HEP::edm4hep EDM4HEP::edm4hepDict ${GSL_LIBRARIES} ) diff --git a/Utilities/DataHelper/DataHelper/ClusterShapes.h b/Utilities/DataHelper/DataHelper/ClusterShapes.h index 695dabeed2be2e97cde2217b8340e04fee8f78c6..3bcd5db00b82fdeefc21e70afe0843f376be2ec2 100644 --- a/Utilities/DataHelper/DataHelper/ClusterShapes.h +++ b/Utilities/DataHelper/DataHelper/ClusterShapes.h @@ -8,7 +8,7 @@ #include <string> #include <sstream> #include <cstdlib> -#include "DataHelper/HelixClass.h" +#include "HelixClass.h" #include <math.h> @@ -24,7 +24,7 @@ */ class ClusterShapes { - public: +public: /** * Constructor @@ -48,20 +48,20 @@ class ClusterShapes { /** * Defining errors for Helix Fit */ - void setErrors(float *ex, float* ey, float *ez); + void setErrors(float *ex, float* ey, float *ez); - /** - * Defining hit types for Helix Fit : - * type 1 - cyllindrical detector - * type 2 - Z disk detector - */ - void setHitTypes(int *ityp); + /** + * Defining hit types for Helix Fit : + * type 1 - cyllindrical detector + * type 2 - Z disk detector + */ + void setHitTypes(int *ityp); /** * returns the number of elements of the cluster */ - int getNumberOfHits(); + int getNumberOfHits(); /** * returns the accumulated amplitude for the whole cluster (just the sum of the @@ -75,15 +75,21 @@ class ClusterShapes { * of gravity is calculated with the energy of the entries of the cluster. */ float* getCentreOfGravity(); + // this is (for now) a pure dummy to allow MarlinPandora development! + float* getCentreOfGravityErrors(); /** US spelling of getCentreOfGravity */ inline float* getCenterOfGravity() { return getCentreOfGravity() ; } + // this is (for now) a pure dummy to allow MarlinPandora development! + inline float* getCenterOfGravityErrors() { return getCentreOfGravityErrors() ; } /** * array of the inertias of mass (i.\ e.\ energy) corresponding to the three main axes * of inertia. The array is sorted in ascending order. */ float* getEigenValInertia(); + // this is (for now) a pure dummy to allow MarlinPandora development! + float* getEigenValInertiaErrors(); /** * array of the three main axes of inertia (9 entries) starting @@ -92,6 +98,8 @@ class ClusterShapes { * of 1. */ float* getEigenVecInertia(); + // this is (for now) a pure dummy to allow MarlinPandora development! + float* getEigenVecInertiaErrors(); /** * 'mean' width of the cluster perpendicular to the main @@ -144,7 +152,7 @@ class ClusterShapes { * detector this is meant to be the 'mean' Moliere radius. */ int fit3DProfile(float& chi2, float& a, float& b, float& c, float& d, float& xl0, - float * xStart, int& index_xStart, float X0, float Rm); + float * xStart, int& index_xStart, float* X0, float* Rm); /** * returns the chi2 of the fit in the method Fit3DProfile (if simple @@ -155,8 +163,8 @@ class ClusterShapes { * @param Rm : Moliere radius of the the detector material. For a composite * detector this is meant to be the 'mean' Moliere radius. */ - float getChi2Fit3DProfileSimple(float a, float b, float c, float d, float X0, - float Rm); + float getChi2Fit3DProfileSimple(float a, float b, float c, float d, float* X0, + float* Rm); /** * returns the chi2 of the fit in the method Fit3DProfile (if advanced @@ -168,7 +176,7 @@ class ClusterShapes { * detector this is meant to be the 'mean' Moliere radius. */ float getChi2Fit3DProfileAdvanced(float E0, float a, float b, float d, float t0, - float X0, float Rm); + float* X0, float* Rm); /** * performs a least square fit on a helix path in space, which @@ -220,6 +228,21 @@ class ClusterShapes { int FitHelix(int max_iter, int status_out, int parametrisation, float* parameter, float* dparameter, float& chi2, float& distmax, int direction=1); + //here add my functions(variables estimated with detector base) + //maximum deposit energy of hits + float getEmax(float* xStart, int& index_xStart, float* X0, float* Rm); + + //shower max of the hits from the shower start hit + float getsmax(float* xStart, int& index_xStart, float* X0, float* Rm); + + //radius where 90% of the cluster energy exists + float getxt90(float* xStart, int& index_xStart, float* X0, float* Rm); + + //length where less than 20% of the cluster energy exists + float getxl20(float* xStart, int& index_xStart, float* X0, float* Rm); + + //for cluster study + void gethits(float* xStart, int& index_xStart, float* X0, float* Rm, float *okxl, float *okxt, float *oke); /** * distance to the centre of gravity measured from IP * (absolut value of the vector to the centre of gravity) @@ -280,54 +303,58 @@ class ClusterShapes { */ inline float getElipsoid_r_back() { return _r1_back; } + //Mean of the radius of the hits + float getRhitMean(float* xStart, int& index_xStart, float* X0, float* Rm); + //RMS of the radius of the hits + float getRhitRMS(float* xStart, int& index_xStart, float* X0, float* Rm); - private: +private: int _nHits; - float* _aHit; - float* _xHit; - float* _yHit; - float* _zHit; - float* _exHit; - float* _eyHit; - float* _ezHit; - int* _types; - float* _xl; - float* _xt; - float* _t; - float* _s; - - int _ifNotGravity; - float _totAmpl; - float _radius; - float _xgr; - float _ygr; - float _zgr; - float _analogGravity[3]; - - int _ifNotWidth; - float _analogWidth; - - int _ifNotInertia; + std::vector<float> _aHit; + std::vector<float> _xHit; + std::vector<float> _yHit; + std::vector<float> _zHit; + std::vector<float> _exHit; + std::vector<float> _eyHit; + std::vector<float> _ezHit; + std::vector<float> _xl; + std::vector<float> _xt; + std::vector<float> _t; + std::vector<float> _s; + std::vector<int> _types; + + int _ifNotGravity=1; + float _totAmpl=0.0; + float _radius=0.0; + float _xgr=0.0; + float _ygr=0.0; + float _zgr=0.0; + float _analogGravity[3]={0.0, 0.0,0.0}; + + int _ifNotWidth=1; + float _analogWidth=0.0; + + int _ifNotInertia=1; float _ValAnalogInertia[3]; float _VecAnalogInertia[9]; - int _ifNotEigensystem; + int _ifNotEigensystem=1; - int _ifNotElipsoid; - float _r1 ; // Cluster spatial axis length -- the largest - float _r2 ; // Cluster spatial axis length -- less - float _r3 ; // Cluster spatial axis length -- less - float _vol ; // Cluster ellipsoid volume - float _r_ave ; // Cluster average radius (qubic root) - float _density ; // Cluster density - float _eccentricity ; // Cluster Eccentricity - float _r1_forw ; - float _r1_back ; + //int _ifNotElipsoid=1; + float _r1 =0.0; // Cluster spatial axis length -- the largest + float _r2 =0.0; // Cluster spatial axis length -- less + float _r3 =0.0; // Cluster spatial axis length -- less + float _vol =0.0; // Cluster ellipsoid volume + float _r_ave =0.0; // Cluster average radius (qubic root) + float _density =0.0; // Cluster density + float _eccentricity =0.0; // Cluster Eccentricity + float _r1_forw =0.0; + float _r1_back =0.0; void findElipsoid(); void findGravity(); @@ -337,8 +364,8 @@ class ClusterShapes { float vecProduct(float * x1, float * x2); float vecProject(float * x, float * axis); double DistanceHelix(double x, double y, double z, double X0, double Y0, double R0, double bz, - double phi0, double * distRPhiZ); - int transformToEigensystem(float* xStart, int& index_xStart, float X0, float Xm); + double phi0, double * distRPhiZ); + int transformToEigensystem(float* xStart, int& index_xStart, float* X0, float* Xm); float calculateChi2Fit3DProfileSimple(float a, float b, float c, float d); float calculateChi2Fit3DProfileAdvanced(float E0, float a, float b, float d, float t0); int fit3DProfileSimple(float& chi2, float& a, float& b, float& c, float& d); @@ -353,4 +380,5 @@ class ClusterShapes { }; + #endif diff --git a/Utilities/DataHelper/src/ClusterShapes.cc b/Utilities/DataHelper/src/ClusterShapes.cc index e86bcefac13f546dbea1292567c2e841c3b62cad..a5fbba971fde00a57acd352bc325d9cd3f5d2d96 100644 --- a/Utilities/DataHelper/src/ClusterShapes.cc +++ b/Utilities/DataHelper/src/ClusterShapes.cc @@ -1,3 +1,5 @@ + + /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ #include "DataHelper/ClusterShapes.h" @@ -14,7 +16,6 @@ //#include <gsl/gsl_sf_pow_int.h> - // ################################################# // ##### ##### // ##### Additional Structures and Functions ##### @@ -46,7 +47,7 @@ double G(double x) { // inverse Gammafunction double invG(double x) { - return gsl_sf_gammainv(x); + return gsl_sf_gammainv(x); } @@ -68,24 +69,23 @@ double DinvG(double x) { double rel_error = 1e-6; double result = 0.0; double error = 0.0; - int status = 0; gsl_integration_workspace* w = gsl_integration_workspace_alloc(workspace_size); gsl_function F; F.function = &Integral_G; F.params = &x; - status = gsl_integration_qagiu(&F,0,abs_error,rel_error,workspace_size,w, - &result,&error); + /*int status=*/gsl_integration_qagiu(&F,0,abs_error,rel_error,workspace_size,w, + &result,&error); // debug /* - printf ("Numeric Integration : \n"); - printf ("parameter of integration = % .18f\n", x); - printf ("status of integration = %d \n" , status); - printf ("result = % .18f\n", result); - printf ("estimated error = % .18f\n", error); - printf ("intervals = %d\n\n", w->size); + printf ("Numeric Integration : \n"); + printf ("parameter of integration = % .18f\n", x); + printf ("status of integration = %d \n" , status); + printf ("result = % .18f\n", result); + printf ("estimated error = % .18f\n", error); + printf ("intervals = %d\n\n", w->size); */ double G2 = pow(gsl_sf_gamma(x),2); @@ -128,7 +128,7 @@ int ShapeFitFunct(const gsl_vector* par, void* d, gsl_vector* f) { for (int i(0); i < n; i++) { fi = /*E0 * */ B * invG(A) * pow(B*(t[i]-t0),A-1) * exp(-B*(t[i]-t0)) * exp(-D*s[i]) - - a[i]; + - a[i]; gsl_vector_set(f,i,fi); } @@ -155,30 +155,30 @@ int dShapeFitFunct(const gsl_vector* par, void* d, gsl_matrix* J) { for (int i(0); i < n; i++) { /* - gsl_matrix_set(J,i,0,B * invG(A) * pow(B*(t[i]-t0),A-1) * exp(-B*(t[i]-t0)) - * exp(-D*s[i]) ); - */ + gsl_matrix_set(J,i,0,B * invG(A) * pow(B*(t[i]-t0),A-1) * exp(-B*(t[i]-t0)) + * exp(-D*s[i]) ); + */ gsl_matrix_set(J,i,0,( /* E0 * */ B * invG(A) * log(B*(t[i]-t0))*pow(B*(t[i]-t0),A-1) * exp(-B*(t[i]-t0)) + DinvG(A) * /* E0 * */ B * pow(B*(t[i]-t0),A-1) * - exp(-B*(t[i]-t0)) - ) * exp(-D*s[i])); + exp(-B*(t[i]-t0)) + ) * exp(-D*s[i])); gsl_matrix_set(J,i,1,( /* E0 * */ invG(A) * pow(B*(t[i]-t0),A-1) * exp(-B*(t[i]-t0)) + /* E0 * */ invG(A) * (A-1) * B * (t[i]-t0) * pow(B*(t[i]-t0),A-2) * - exp(-B*(t[i]-t0)) - + exp(-B*(t[i]-t0)) - /* E0 * */ B * invG(A) * (t[i]-t0) * pow(B*(t[i]-t0),A-1) * - exp(-B*(t[i]-t0)) - ) * exp(-D*s[i])); + exp(-B*(t[i]-t0)) + ) * exp(-D*s[i])); gsl_matrix_set(J,i,2,-/* E0 * */ B * invG(A) * s[i] * pow(B*(t[i]-t0),A-1) * - exp(-B*(t[i]-t0)) * exp(-D*s[i])); + exp(-B*(t[i]-t0)) * exp(-D*s[i])); gsl_matrix_set(J,i,3,(-/* E0 * */ pow(B,2) * invG(A) * (A-1) * pow(B*(t[i]-t0),A-2) * - exp(-B*(t[i]-t0)) + - /* E0 * */ pow(B,2) * invG(A) * pow(B*(t[i]-t0),A-1) * - exp(-B*(t[i]-t0)) - ) * exp(-D*s[i])); + exp(-B*(t[i]-t0)) + + /* E0 * */ pow(B,2) * invG(A) * pow(B*(t[i]-t0),A-1) * + exp(-B*(t[i]-t0)) + ) * exp(-D*s[i])); } @@ -229,9 +229,9 @@ int functParametrisation1(const gsl_vector* par, void* d, gsl_vector* f) { float* x = ((struct data*)d)->x; float* y = ((struct data*)d)->y; float* z = ((struct data*)d)->z; -//float* ex = ((struct data*)d)->ex; -//float* ey = ((struct data*)d)->ey; -//float* ez = ((struct data*)d)->ez; + //float* ex = ((struct data*)d)->ex; + //float* ey = ((struct data*)d)->ey; + //float* ez = ((struct data*)d)->ez; float fi = 0.0; // first dimension @@ -263,9 +263,9 @@ int dfunctParametrisation1(const gsl_vector* par, void* d, gsl_matrix* J) { int n = ((struct data*)d)->n; float* z = ((struct data*)d)->z; -//float* ex = ((struct data*)d)->ex; -//float* ey = ((struct data*)d)->ey; -//float* ez = ((struct data*)d)->ez; + //float* ex = ((struct data*)d)->ex; + //float* ey = ((struct data*)d)->ey; + //float* ez = ((struct data*)d)->ez; // calculate Jacobi's matrix J[i][j] = dfi/dparj @@ -508,7 +508,7 @@ int dfunctParametrisation3(const gsl_vector* par, void* d, gsl_matrix* J) { gsl_matrix_set(J,i,0,0); gsl_matrix_set(J,i,1,((1/omega) - d0) * cos(Phi0) - (1/fabs(omega)) * sin(phii) ); gsl_matrix_set(J,i,2,((-1.0)*sin(Phi0))/pow(omega,2) - ( (signum(omega))/(pow(fabs(omega),2)) ) * cos(phii) - - (1/fabs(omega)) * sin(phii) * ( ( ((-1.0)/sqrt(1+pow(tanL,2)))*si) + (M_PI)/(2*fabs(omega)) - (signum(omega)*omega*M_PI)/(2*pow(fabs(omega),2)) ) ); + (1/fabs(omega)) * sin(phii) * ( ( ((-1.0)/sqrt(1+pow(tanL,2)))*si) + (M_PI)/(2*fabs(omega)) - (signum(omega)*omega*M_PI)/(2*pow(fabs(omega),2)) ) ); gsl_matrix_set(J,i,3,(-1.0)*sin(Phi0)); gsl_matrix_set(J,i,4,((-1.0)/fabs(omega))*sin(phii) * ( (omega*tanL*si)/sqrt(pow(1+pow(tanL,2),3)) ) ); @@ -522,7 +522,7 @@ int dfunctParametrisation3(const gsl_vector* par, void* d, gsl_matrix* J) { gsl_matrix_set(J,i+n,0,0); gsl_matrix_set(J,i+n,1,((1/omega) - d0)*sin(Phi0) + (1/fabs(omega)) * cos(phii) ); gsl_matrix_set(J,i+n,2,cos(Phi0)/pow(omega,2) + ( (signum(omega))/(pow(fabs(omega),2)) ) * sin(phii) + - (1/fabs(omega))*cos(phii) * ( ( ((-1.0)/sqrt(1+pow(tanL,2)))*si) + (M_PI)/(2*fabs(omega)) - (signum(omega)*omega*M_PI)/(2*pow(fabs(omega),2)) ) ); + (1/fabs(omega))*cos(phii) * ( ( ((-1.0)/sqrt(1+pow(tanL,2)))*si) + (M_PI)/(2*fabs(omega)) - (signum(omega)*omega*M_PI)/(2*pow(fabs(omega),2)) ) ); gsl_matrix_set(J,i+n,3,cos(Phi0)); gsl_matrix_set(J,i+n,4,(1/fabs(omega))*cos(phii) * ( (omega*tanL*si)/sqrt(pow(1+pow(tanL,2),3)) ) ); @@ -570,39 +570,35 @@ int fdfParametrisation3(const gsl_vector* par, void* d, gsl_vector* f, gsl_matri //============================================================================= -ClusterShapes::ClusterShapes(int nhits, float* a, float* x, float* y, float* z){ - - _nHits = nhits; - _aHit = new float[_nHits]; - _xHit = new float[_nHits]; - _yHit = new float[_nHits]; - _zHit = new float[_nHits]; - _exHit = new float[_nHits]; - _eyHit = new float[_nHits]; - _ezHit = new float[_nHits]; - _types = new int[_nHits]; - - _xl = new float[_nHits]; - _xt = new float[_nHits]; - - _t = new float[_nHits]; - _s = new float[_nHits]; +ClusterShapes::ClusterShapes(int nhits, float* a, float* x, float* y, float* z): + + _nHits(nhits), + _aHit (nhits, 0.0), + _xHit (nhits, 0.0), + _yHit (nhits, 0.0), + _zHit (nhits, 0.0), + _exHit (nhits, 1.0), + _eyHit (nhits, 1.0), + _ezHit (nhits, 1.0), + _xl (nhits, 0.0), + _xt (nhits, 0.0), + _t (nhits, 0.0), + _s (nhits, 0.0), + _types(nhits, 1), // all hits are assumed to be "cylindrical" + + _ifNotGravity (1), + _ifNotWidth (1), + _ifNotInertia (1), + _ifNotEigensystem(1) +{ for (int i(0); i < nhits; ++i) { _aHit[i] = a[i]; _xHit[i] = x[i]; _yHit[i] = y[i]; _zHit[i] = z[i]; - _exHit[i] = 1.0; - _eyHit[i] = 1.0; - _ezHit[i] = 1.0; - _types[i] = 1; // all hits are assumed to be "cyllindrical" } - _ifNotGravity = 1; - _ifNotWidth = 1; - _ifNotInertia = 1; - _ifNotEigensystem = 1; } @@ -611,18 +607,6 @@ ClusterShapes::ClusterShapes(int nhits, float* a, float* x, float* y, float* z){ ClusterShapes::~ClusterShapes() { - delete[] _aHit; - delete[] _xHit; - delete[] _yHit; - delete[] _zHit; - delete[] _exHit; - delete[] _eyHit; - delete[] _ezHit; - delete[] _types; - delete[] _xl; - delete[] _xt; - delete[] _t; - delete[] _s; } //============================================================================= @@ -672,6 +656,11 @@ float* ClusterShapes::getCentreOfGravity() { if (_ifNotGravity == 1) findGravity() ; return &_analogGravity[0] ; } +float* ClusterShapes::getCentreOfGravityErrors() { + // this is a pure dummy to allow MarlinPandora development! + if (_ifNotGravity == 1) findGravity() ; + return &_analogGravity[0] ; +} //============================================================================= @@ -679,6 +668,11 @@ float* ClusterShapes::getEigenValInertia() { if (_ifNotInertia == 1) findInertia(); return &_ValAnalogInertia[0] ; } +float* ClusterShapes::getEigenValInertiaErrors() { + // this is a pure dummy to allow MarlinPandora development! + if (_ifNotInertia == 1) findInertia(); + return &_ValAnalogInertia[0] ; +} //============================================================================= @@ -686,6 +680,11 @@ float* ClusterShapes::getEigenVecInertia() { if (_ifNotInertia == 1) findInertia(); return &_VecAnalogInertia[0] ; } +float* ClusterShapes::getEigenVecInertiaErrors() { + // this is a pure dummy to allow MarlinPandora development! + if (_ifNotInertia == 1) findInertia(); + return &_VecAnalogInertia[0] ; +} //============================================================================= @@ -703,8 +702,8 @@ int ClusterShapes::getEigenSytemCoordinates(float* xlong, float* xtrans) { // NOT SAVE, change to class variables !!!!! - float X0 = 7.0; - float Rm = 13.5; + float X0[2]={3.50,17.57}; //in mm. //this is the exact value of tungsten and iron + float Rm[2]={9.00,17.19}; //in mm. need to change to estimate correctly if (_ifNotEigensystem == 1) transformToEigensystem(xStart,index_xStart,X0,Rm); @@ -725,8 +724,8 @@ int ClusterShapes::getEigenSytemCoordinates(float* xlong, float* xtrans, float* int index_xStart; // NOT SAVE, change to class variables !!!!! - float X0 = 7.0; - float Rm = 13.5; + float X0[2]={3.50,17.57}; //in mm. //this is the exact value of tungsten and iron + float Rm[2]={9.00,17.19}; //in mm. need to change to estimate correctly if (_ifNotEigensystem == 1) transformToEigensystem(xStart,index_xStart,X0,Rm); @@ -744,15 +743,25 @@ int ClusterShapes::getEigenSytemCoordinates(float* xlong, float* xtrans, float* int ClusterShapes::fit3DProfile(float& chi2, float& E0, float& A, float& B, float& D, float& xl0, float* xStart, int& index_xStart, - float X0, float Rm) { + float* X0, float* Rm) { const int npar = 4; - - if (_ifNotEigensystem == 1) transformToEigensystem(xStart,index_xStart,X0,Rm); - + if (_ifNotEigensystem == 1){ + transformToEigensystem(xStart,index_xStart,X0,Rm); + } + float* E = new float[_nHits]; + //doesn't fit when _nHits==0 + //std::cout << "_nhits " << _nHits << std::endl; + if(_nHits-1 < npar){ //can't fit because number of degrees of freedom is small + E0=0.0; + + delete[] E; + int result = 0; // no error handling at the moment + return result; + } double par_init[npar]; for (int i = 0; i < npar; ++i) par_init[i] = 0.0; // initialise @@ -760,16 +769,16 @@ int ClusterShapes::fit3DProfile(float& chi2, float& E0, float& A, float& B, floa float E0_init = 0.0; float A_init = 0.0; float B_init = 0.5; // empirically - float D_init = 0.5; // empirically - float t0_init = -10.0/X0; // shift xl0_ini is assumed to be -10.0 without a reason ???? + float D_init = 0.06; //0.5; //if Rm includes 90% of shower energy, absorption length has 63% of shower energy + float t0_init = -10.0/X0[0]; // shift xl0_ini is assumed to be -10.0 without a reason ???? float E0_tmp = 0.0; - int i_max = 0; - float t_max = 0.0; + // int i_max = 0; + //float t_max = 0.0; for (int i = 0; i < _nHits; ++i) { if (E0_tmp < _aHit[i]) { E0_tmp = _aHit[i]; - i_max = i; + //i_max = i; } E0_init += _aHit[i]; } @@ -783,11 +792,9 @@ int ClusterShapes::fit3DProfile(float& chi2, float& E0, float& A, float& B, floa //A_init = t_max*B_init + 1.0; // third definition - float Ec = X0 * 0.021/Rm; + float Ec = X0[0] * 0.021/Rm[0]; A_init = B_init * log(E0_init/Ec) + 0.5 * B_init + 1.0; // (+0.5 for Photons initiated showers) - - // par_init[0] = E0_init; E0 = E0_init; for (int i = 0; i < _nHits; ++i) E[i] = _aHit[i]/E0_init; @@ -795,28 +802,28 @@ int ClusterShapes::fit3DProfile(float& chi2, float& E0, float& A, float& B, floa par_init[1] = B_init; par_init[2] = D_init; par_init[3] = t0_init; - + // debug - std::cout << "E0_init : " << E0_init << "\t" << "A_init : " << A_init << "\t" - << "B_init : " << B_init << "\t" << "D_init : " << D_init << "\t" - << "xl0_init : " << t0_init*X0 << "\t" << "X0 : " << X0 - << "\t" << "t_max : " << t_max << std::endl << std::endl; + // std::cout << "E0_init : " << E0_init << "\t" << "A_init : " << A_init << "\t" + // << "B_init : " << B_init << "\t" << "D_init : " << D_init << "\t" + // << "xl0_init : " << t0_init*X0 << "\t" << "X0 : " << X0 + // << "\t" << "t_max : " << t_max << std::endl << std::endl; - double t0 = xl0/X0; + double t0 = xl0/X0[0]; //probably t0 is in ecal double par[npar]; par[0] = A; par[1] = B; par[2] = D; par[3] = t0; - fit3DProfileAdvanced(chi2,par_init,par,npar,_t,_s,E,E0); + fit3DProfileAdvanced(chi2,par_init,par,npar,&_t[0],&_s[0],E,E0); A = par[0]; B = par[1]; D = par[2]; - xl0 = par[3] * X0; + xl0 = par[3] * X0[0]; //probably shower start is in ecal delete[] E; @@ -827,7 +834,7 @@ int ClusterShapes::fit3DProfile(float& chi2, float& E0, float& A, float& B, floa //============================================================================= float ClusterShapes::getChi2Fit3DProfileSimple(float a, float b, float c, float d, - float X0, float Rm) { + float* X0, float* Rm) { float chi2 = 0.0; @@ -845,7 +852,7 @@ float ClusterShapes::getChi2Fit3DProfileSimple(float a, float b, float c, float //============================================================================= float ClusterShapes::getChi2Fit3DProfileAdvanced(float E0, float a, float b, float d, - float t0, float X0, float Rm) { + float t0, float* X0, float* Rm) { float chi2 = 0.0; @@ -897,18 +904,18 @@ int ClusterShapes::FitHelix(int max_iter, int status_out, int parametrisation, int ClusterShapes::FitHelix(int max_iter, int status_out, int parametrisation, double* parameter, double* dparameter, double& chi2, - double& distmax, int direction) { + double& distmax, int direction) { // FIXME: version with double typed parameters needed 2006/06/10 OW if (_nHits < 3) { - std::cout << "ClusterShapes : helix fit impossible, two few points" ; - std::cout << std::endl; - for (int i = 0; i < 5; ++i) { - parameter[i] = 0.0; - dparameter[i] = 0.0; - } - return 1; + std::cout << "ClusterShapes : helix fit impossible, two few points" ; + std::cout << std::endl; + for (int i = 0; i < 5; ++i) { + parameter[i] = 0.0; + dparameter[i] = 0.0; + } + return 1; } // find initial parameters @@ -919,14 +926,14 @@ int ClusterShapes::FitHelix(int max_iter, int status_out, int parametrisation, // 1st loop for (int i(0); i < _nHits; ++i) { - double Rz = sqrt(_xHit[i]*_xHit[i] + _yHit[i]*_yHit[i]); - if (Rz < Rmin) { - Rmin = Rz; - i1 = i; - } - if (Rz > Rmax) { - Rmax = Rz; - } + double Rz = sqrt(_xHit[i]*_xHit[i] + _yHit[i]*_yHit[i]); + if (Rz < Rmin) { + Rmin = Rz; + i1 = i; + } + if (Rz > Rmax) { + Rmax = Rz; + } } @@ -934,8 +941,8 @@ int ClusterShapes::FitHelix(int max_iter, int status_out, int parametrisation, // debug /* - for (int i(0); i < _nHits; ++i) std::cout << i << " " << _xHit[i] << " " << _yHit[i] << " " << _zHit[i] << std::endl; - std::cout << std::endl << Rmin << " " << Rmax << " " << i1 << std::endl; + for (int i(0); i < _nHits; ++i) std::cout << i << " " << _xHit[i] << " " << _yHit[i] << " " << _zHit[i] << std::endl; + std::cout << std::endl << Rmin << " " << Rmax << " " << i1 << std::endl; */ @@ -954,8 +961,8 @@ int ClusterShapes::FitHelix(int max_iter, int status_out, int parametrisation, if ((Rz > Lower) && (Rz < Upper)) { double dZ = fabs(_zHit[i]-_zHit[i1]); if (dZ < dZmin) { - dZmin = dZ; - i3 = i; + dZmin = dZ; + i3 = i; } } } @@ -977,35 +984,35 @@ int ClusterShapes::FitHelix(int max_iter, int status_out, int parametrisation, // 3d loop for (int i(0); i < _nHits; ++i) { - if (_zHit[i] >= z1 && _zHit[i] <= z3) { - double Rz = sqrt(_xHit[i]*_xHit[i] + _yHit[i]*_yHit[i]); - double dRz = fabs(Rz - Rref); - if (dRz < dRmin) { - i2 = i; - dRmin = dRz; - } + if (_zHit[i] >= z1 && _zHit[i] <= z3) { + double Rz = sqrt(_xHit[i]*_xHit[i] + _yHit[i]*_yHit[i]); + double dRz = fabs(Rz - Rref); + if (dRz < dRmin) { + i2 = i; + dRmin = dRz; } + } } - int problematic = 0; + //int problematic = 0; if (i2 < 0 || i2 == i1 || i2 == i3) { - problematic = 1; + //problematic = 1; // std::cout << "here we are " << std::endl; for (int i(0); i < _nHits; ++i) { if (i != i1 && i != i3) { - i2 = i; - if (_zHit[i2] < z1) { - int itemp = i1; - i1 = i2; - i2 = itemp; - } - else if (_zHit[i2] > z3) { - int itemp = i3; - i3 = i2; - i2 = itemp; - } - break; + i2 = i; + if (_zHit[i2] < z1) { + int itemp = i1; + i1 = i2; + i2 = itemp; + } + else if (_zHit[i2] > z3) { + int itemp = i3; + i3 = i2; + i2 = itemp; + } + break; } } // std::cout << i1 << " " << i2 << " " << i3 << std::endl; @@ -1024,23 +1031,23 @@ int ClusterShapes::FitHelix(int max_iter, int status_out, int parametrisation, double time; if (det == 0.) { - time = 500.; + time = 500.; } else { - gsl_matrix* A = gsl_matrix_alloc(2,2); - gsl_vector* B = gsl_vector_alloc(2); - gsl_vector* T = gsl_vector_alloc(2); - gsl_matrix_set(A,0,0,ax); - gsl_matrix_set(A,0,1,-axp); - gsl_matrix_set(A,1,0,ay); - gsl_matrix_set(A,1,1,-ayp); - gsl_vector_set(B,0,x0p-x0); - gsl_vector_set(B,1,y0p-y0); - gsl_linalg_HH_solve(A,B,T); - time = gsl_vector_get(T,0); - gsl_matrix_free(A); - gsl_vector_free(B); - gsl_vector_free(T); + gsl_matrix* A = gsl_matrix_alloc(2,2); + gsl_vector* B = gsl_vector_alloc(2); + gsl_vector* T = gsl_vector_alloc(2); + gsl_matrix_set(A,0,0,ax); + gsl_matrix_set(A,0,1,-axp); + gsl_matrix_set(A,1,0,ay); + gsl_matrix_set(A,1,1,-ayp); + gsl_vector_set(B,0,x0p-x0); + gsl_vector_set(B,1,y0p-y0); + gsl_linalg_HH_solve(A,B,T); + time = gsl_vector_get(T,0); + gsl_matrix_free(A); + gsl_vector_free(B); + gsl_vector_free(T); } double X0 = x0 + ax*time; @@ -1052,44 +1059,44 @@ int ClusterShapes::FitHelix(int max_iter, int status_out, int parametrisation, double R0 = sqrt(dX*dX + dY*dY); /* - if (problematic == 1) { - std::cout << i1 << " " << i2 << " " << i3 << std::endl; - std::cout << _xHit[i1] << " " << _yHit[i1] << " " << _zHit[i1] << std::endl; - std::cout << _xHit[i2] << " " << _yHit[i2] << " " << _zHit[i2] << std::endl; - std::cout << _xHit[i3] << " " << _yHit[i3] << " " << _zHit[i3] << std::endl; - std::cout << "R0 = " << R0 << std::endl; - } + if (problematic == 1) { + std::cout << i1 << " " << i2 << " " << i3 << std::endl; + std::cout << _xHit[i1] << " " << _yHit[i1] << " " << _zHit[i1] << std::endl; + std::cout << _xHit[i2] << " " << _yHit[i2] << " " << _zHit[i2] << std::endl; + std::cout << _xHit[i3] << " " << _yHit[i3] << " " << _zHit[i3] << std::endl; + std::cout << "R0 = " << R0 << std::endl; + } */ double phi1 = (double)atan2(_yHit[i1]-Y0,_xHit[i1]-X0); double phi2 = (double)atan2(_yHit[i2]-Y0,_xHit[i2]-X0); double phi3 = (double)atan2(_yHit[i3]-Y0,_xHit[i3]-X0); -// testing bz > 0 hypothesis + // testing bz > 0 hypothesis if ( phi1 > phi2 ) - phi2 = phi2 + 2.0*M_PI; + phi2 = phi2 + 2.0*M_PI; if ( phi1 > phi3 ) - phi3 = phi3 + 2.0*M_PI; + phi3 = phi3 + 2.0*M_PI; if ( phi2 > phi3 ) - phi3 = phi3 + 2.0*M_PI; + phi3 = phi3 + 2.0*M_PI; double bz_plus = (phi3 - phi1) / (_zHit[i3]-_zHit[i1]); double phi0_plus = phi1 - bz_plus * _zHit[i1]; double dphi_plus = fabs( bz_plus * _zHit[i2] + phi0_plus - phi2 ); -// testing bz < 0 hypothesis + // testing bz < 0 hypothesis phi1 = (double)atan2(_yHit[i1]-Y0,_xHit[i1]-X0); phi2 = (double)atan2(_yHit[i2]-Y0,_xHit[i2]-X0); phi3 = (double)atan2(_yHit[i3]-Y0,_xHit[i3]-X0); if ( phi1 < phi2 ) - phi2 = phi2 - 2.0*M_PI; + phi2 = phi2 - 2.0*M_PI; if ( phi1 < phi3 ) - phi3 = phi3 - 2.0*M_PI; + phi3 = phi3 - 2.0*M_PI; if ( phi2 < phi3 ) - phi3 = phi3 - 2.0*M_PI; + phi3 = phi3 - 2.0*M_PI; double bz_minus = (phi3 - phi1) / (_zHit[i3]-_zHit[i1]); double phi0_minus = phi1 - bz_minus * _zHit[i1]; @@ -1099,12 +1106,12 @@ int ClusterShapes::FitHelix(int max_iter, int status_out, int parametrisation, double phi0; if (dphi_plus < dphi_minus) { - bz = bz_plus; - phi0 = phi0_plus; + bz = bz_plus; + phi0 = phi0_plus; } else { - bz = bz_minus; - phi0 = phi0_minus; + bz = bz_minus; + phi0 = phi0_minus; } @@ -1133,11 +1140,11 @@ int ClusterShapes::FitHelix(int max_iter, int status_out, int parametrisation, // debug /* - X0 = -1205.28; - Y0 = 175.317; - R0 = 1217.97; - bz = 0.00326074; - phi0 = -0.144444; + X0 = -1205.28; + Y0 = 175.317; + R0 = 1217.97; + bz = 0.00326074; + phi0 = -0.144444; */ @@ -1176,17 +1183,17 @@ int ClusterShapes::FitHelix(int max_iter, int status_out, int parametrisation, // debug /* - std::cout << std::setprecision(6) << "InitFitCalculated (d0,z0,phi0,omega,tanL) = " << "(" << d0 << "," << z0 << "," << Phi0 << "," << omega << "," << tanL << ")" - << " " << "sign(omega) = " << direction << std::endl; + std::cout << std::setprecision(6) << "InitFitCalculated (d0,z0,phi0,omega,tanL) = " << "(" << d0 << "," << z0 << "," << Phi0 << "," << omega << "," << tanL << ")" + << " " << "sign(omega) = " << direction << std::endl; */ // debug /* - d0 = 0.00016512; - z0 = 0.000853511; - Phi0 = 1.11974; - omega = -4.22171e-05; - tanL = -0.33436; + d0 = 0.00016512; + z0 = 0.000853511; + Phi0 = 1.11974; + omega = -4.22171e-05; + tanL = -0.33436; */ @@ -1223,7 +1230,7 @@ int ClusterShapes::FitHelix(int max_iter, int status_out, int parametrisation, for (int ipoint(0); ipoint < _nHits; ipoint++) { double distRPZ[2]; double Dist = DistanceHelix(_xHit[ipoint],_yHit[ipoint],_zHit[ipoint], - X0,Y0,R0,bz,phi0,distRPZ); + X0,Y0,R0,bz,phi0,distRPZ); double chi2rphi = distRPZ[0]/_exHit[ipoint]; chi2rphi = chi2rphi*chi2rphi; double chi2z = distRPZ[1]/_ezHit[ipoint]; @@ -1306,7 +1313,11 @@ int ClusterShapes::FitHelix(int max_iter, int status_out, int parametrisation, } while ( status==GSL_CONTINUE && iter < max_iter); - gsl_multifit_covar (s->J, rel_error, covar); + //fg: jacobian has been dropped from gsl_multifit_fdfsolver in gsl 2: + gsl_matrix * J = gsl_matrix_alloc(s->fdf->n, s->fdf->p); + gsl_multifit_fdfsolver_jac( s, J); + gsl_multifit_covar( J, rel_error, covar ); + // gsl_multifit_covar (s->J, rel_error, covar); @@ -1347,7 +1358,7 @@ int ClusterShapes::FitHelix(int max_iter, int status_out, int parametrisation, for (int ipoint(0); ipoint < _nHits; ipoint++) { double distRPZ[2]; double Dist = DistanceHelix(_xHit[ipoint],_yHit[ipoint],_zHit[ipoint], - X0,Y0,R0,bz,phi0,distRPZ); + X0,Y0,R0,bz,phi0,distRPZ); double chi2rphi = distRPZ[0]/_exHit[ipoint]; chi2rphi = chi2rphi*chi2rphi; double chi2z = distRPZ[1]/_ezHit[ipoint]; @@ -1446,23 +1457,23 @@ void ClusterShapes::findElipsoid() { void ClusterShapes::findGravity() { - _totAmpl = 0. ; - for (int i(0); i < 3; ++i) { - _analogGravity[i] = 0.0 ; - } - for (int i(0); i < _nHits; ++i) { - _totAmpl+=_aHit[i] ; - _analogGravity[0]+=_aHit[i]*_xHit[i] ; - _analogGravity[1]+=_aHit[i]*_yHit[i] ; - _analogGravity[2]+=_aHit[i]*_zHit[i] ; - } - for (int i(0); i < 3; ++i) { - _analogGravity[i]/=_totAmpl ; - } - _xgr = _analogGravity[0]; - _ygr = _analogGravity[1]; - _zgr = _analogGravity[2]; - _ifNotGravity = 0; + _totAmpl = 0. ; + for (int i(0); i < 3; ++i) { + _analogGravity[i] = 0.0 ; + } + for (int i(0); i < _nHits; ++i) { + _totAmpl+=_aHit[i] ; + _analogGravity[0]+=_aHit[i]*_xHit[i] ; + _analogGravity[1]+=_aHit[i]*_yHit[i] ; + _analogGravity[2]+=_aHit[i]*_zHit[i] ; + } + for (int i(0); i < 3; ++i) { + _analogGravity[i]/=_totAmpl ; + } + _xgr = _analogGravity[0]; + _ygr = _analogGravity[1]; + _zgr = _analogGravity[2]; + _ifNotGravity = 0; } //============================================================================= @@ -1476,27 +1487,27 @@ void ClusterShapes::findInertia() { findGravity(); for (int i(0); i < 3; ++i) { - for (int j(0); j < 3; ++j) { - aIne[i][j] = 0.0; - } + for (int j(0); j < 3; ++j) { + aIne[i][j] = 0.0; + } } for (int i(0); i < _nHits; ++i) { - float dX = _xHit[i] - _analogGravity[0]; - float dY = _yHit[i] - _analogGravity[1]; - float dZ = _zHit[i] - _analogGravity[2]; - aIne[0][0] += _aHit[i]*(dY*dY+dZ*dZ); - aIne[1][1] += _aHit[i]*(dX*dX+dZ*dZ); - aIne[2][2] += _aHit[i]*(dX*dX+dY*dY); - aIne[0][1] -= _aHit[i]*dX*dY; - aIne[0][2] -= _aHit[i]*dX*dZ; - aIne[1][2] -= _aHit[i]*dY*dZ; + float dX = _xHit[i] - _analogGravity[0]; + float dY = _yHit[i] - _analogGravity[1]; + float dZ = _zHit[i] - _analogGravity[2]; + aIne[0][0] += _aHit[i]*(dY*dY+dZ*dZ); + aIne[1][1] += _aHit[i]*(dX*dX+dZ*dZ); + aIne[2][2] += _aHit[i]*(dX*dX+dY*dY); + aIne[0][1] -= _aHit[i]*dX*dY; + aIne[0][2] -= _aHit[i]*dX*dZ; + aIne[1][2] -= _aHit[i]*dY*dZ; } for (int i(0); i < 2; ++i) { - for (int j = i+1; j < 3; ++j) { - aIne[j][i] = aIne[i][j]; - } + for (int j = i+1; j < 3; ++j) { + aIne[j][i] = aIne[i][j]; + } } //**************************************** // analog Inertia @@ -1523,13 +1534,13 @@ void ClusterShapes::findInertia() { radius2 = 0.; for (int i(0); i < 3; ++i) { - _radius += _analogGravity[i]*_analogGravity[i]; - radius2 += (_analogGravity[i]+_VecAnalogInertia[i])*(_analogGravity[i]+_VecAnalogInertia[i]); + _radius += _analogGravity[i]*_analogGravity[i]; + radius2 += (_analogGravity[i]+_VecAnalogInertia[i])*(_analogGravity[i]+_VecAnalogInertia[i]); } if ( radius2 < _radius) { - for (int i(0); i < 3; ++i) - _VecAnalogInertia[i] = - _VecAnalogInertia[i]; + for (int i(0); i < 3; ++i) + _VecAnalogInertia[i] = - _VecAnalogInertia[i]; } _radius = sqrt(_radius); @@ -1563,99 +1574,99 @@ void ClusterShapes::findWidth() { float ClusterShapes::findDistance(int i) { - float cx = 0.0; - float cy = 0.0; - float cz = 0.0; - float dx = 0.0; - float dy = 0.0; - float dz = 0.0; - cx = _VecAnalogInertia[0] ; - cy = _VecAnalogInertia[1] ; - cz = _VecAnalogInertia[2] ; - dx = _analogGravity[0] - _xHit[i] ; - dy = _analogGravity[1] - _yHit[i] ; - dz = _analogGravity[2] - _zHit[i] ; - float tx = cy*dz - cz*dy ; - float ty = cz*dx - cx*dz ; - float tz = cx*dy - cy*dx ; - float tt = sqrt(tx*tx+ty*ty+tz*tz) ; - float ti = sqrt(cx*cx+cy*cy+cz*cz) ; - float f = tt / ti ; - return f ; + float cx = 0.0; + float cy = 0.0; + float cz = 0.0; + float dx = 0.0; + float dy = 0.0; + float dz = 0.0; + cx = _VecAnalogInertia[0] ; + cy = _VecAnalogInertia[1] ; + cz = _VecAnalogInertia[2] ; + dx = _analogGravity[0] - _xHit[i] ; + dy = _analogGravity[1] - _yHit[i] ; + dz = _analogGravity[2] - _zHit[i] ; + float tx = cy*dz - cz*dy ; + float ty = cz*dx - cx*dz ; + float tz = cx*dy - cy*dx ; + float tt = sqrt(tx*tx+ty*ty+tz*tz) ; + float ti = sqrt(cx*cx+cy*cy+cz*cz) ; + float f = tt / ti ; + return f ; } /** - Function sdist(xp,yp,zp,cx,cy,cz,xv,yv,zv) -c---------------------------------------------------------------------- -c Distance from line to point -c xp, yp, zp -- point is at the line -c xv, yv, zv -- point is out of line -******************************************************************** -* Last update V.L.Morgunov 08-Apr-2002 * -******************************************************************** - real xp,yp,zp,cx,cy,cz,xv,yv,zv,t1,t2,t3,tt,sdist - - t1 = cy*(zp-zv)-cz*(yp-yv) - t2 = cz*(xp-xv)-cx*(zp-zv) - t3 = cx*(yp-yv)-cy*(xp-xv) - tt = sqrt(cx**2+cy**2+cz**2) - sdist = sqrt(t1**2+t2**2+t3**2)/tt - - return - end + Function sdist(xp,yp,zp,cx,cy,cz,xv,yv,zv) + c---------------------------------------------------------------------- + c Distance from line to point + c xp, yp, zp -- point is at the line + c xv, yv, zv -- point is out of line + ******************************************************************** + * Last update V.L.Morgunov 08-Apr-2002 * + ******************************************************************** + real xp,yp,zp,cx,cy,cz,xv,yv,zv,t1,t2,t3,tt,sdist + + t1 = cy*(zp-zv)-cz*(yp-yv) + t2 = cz*(xp-xv)-cx*(zp-zv) + t3 = cx*(yp-yv)-cy*(xp-xv) + tt = sqrt(cx**2+cy**2+cz**2) + sdist = sqrt(t1**2+t2**2+t3**2)/tt + + return + end */ //============================================================================= float ClusterShapes::vecProduct(float * x1, float * x2) { - float x1abs(0.); - float x2abs(0.); - float prod(0.); + float x1abs(0.); + float x2abs(0.); + float prod(0.); - for (int i(0); i < 3; ++i) { - x1abs += x1[i]*x1[i]; - x2abs += x2[i]*x2[i]; - prod += x1[i]*x2[i]; - } + for (int i(0); i < 3; ++i) { + x1abs += x1[i]*x1[i]; + x2abs += x2[i]*x2[i]; + prod += x1[i]*x2[i]; + } - x1abs = sqrt(x1abs); - x2abs = sqrt(x2abs); + x1abs = sqrt(x1abs); + x2abs = sqrt(x2abs); - if (x1abs > 0.0 && x2abs > 0.0) { - prod = prod/(x1abs*x2abs); - } - else { - prod = 0.; - } + if (x1abs > 0.0 && x2abs > 0.0) { + prod = prod/(x1abs*x2abs); + } + else { + prod = 0.; + } - return prod; + return prod; } //============================================================================= float ClusterShapes::vecProject(float * x, float * axis) { - float axisabs(0.); - float prod(0.); - for (int i(0); i < 3; ++i) { - axisabs += axis[i]*axis[i]; - prod += x[i]*axis[i]; - } - axisabs = sqrt(axisabs); - if (axisabs > 0.0 ) { - prod = prod/axisabs; - } - else { - prod = 0.; - } - return prod; + float axisabs(0.); + float prod(0.); + for (int i(0); i < 3; ++i) { + axisabs += axis[i]*axis[i]; + prod += x[i]*axis[i]; + } + axisabs = sqrt(axisabs); + if (axisabs > 0.0 ) { + prod = prod/axisabs; + } + else { + prod = 0.; + } + return prod; } //============================================================================= double ClusterShapes::DistanceHelix(double x, double y, double z, double X0, double Y0, - double R0, double bz, double phi0, double * distRPZ) { + double R0, double bz, double phi0, double * distRPZ) { double phi = atan2(y-Y0,x-X0); double R = sqrt( (y-Y0)*(y-Y0) + (x-X0)*(x-X0) ); @@ -1695,9 +1706,8 @@ double ClusterShapes::DistanceHelix(double x, double y, double z, double X0, dou //============================================================================= -int ClusterShapes::transformToEigensystem(float* xStart, int& index_xStart, float X0, - float Rm) { - +int ClusterShapes::transformToEigensystem(float* xStart, int& index_xStart, float* X0, float* Rm) { + if (_ifNotInertia == 1) findInertia(); float MainAxis[3]; @@ -1711,9 +1721,16 @@ int ClusterShapes::transformToEigensystem(float* xStart, int& index_xStart, floa MainCentre[1] = _analogGravity[1]; MainCentre[2] = _analogGravity[2]; + //analoginertia looks something wrong! + //change it to the direction of CoG + //float ll=sqrt(MainCentre[0]*MainCentre[0]+MainCentre[1]*MainCentre[1]+MainCentre[2]*MainCentre[2]); + //MainAxis[0]=MainCentre[0]/ll; + //MainAxis[1]=MainCentre[1]/ll; + //MainAxis[2]=MainCentre[2]/ll; + int ifirst = 0; float xx[3]; - float prodmin = 0.0; + float prodmin = 1.0e+100; int index = 0; for (int i(0); i < _nHits; ++i) { @@ -1731,27 +1748,73 @@ int ClusterShapes::transformToEigensystem(float* xStart, int& index_xStart, floa xStart[1] = MainCentre[1] + prodmin*MainAxis[1]; xStart[2] = MainCentre[2] + prodmin*MainAxis[2]; index_xStart = index; + + float l=sqrt(MainAxis[0]*MainAxis[0]+MainAxis[1]*MainAxis[1]+MainAxis[2]*MainAxis[2]); + //float ll=sqrt(xStart[0]*xStart[0]+xStart[1]*xStart[1]+xStart[2]*xStart[2]); + //std::cout << "xstart: " << index_xStart << " " << prodmin << " " << xStart[0] << std::endl; + //calculate the surface of hcal + float ecalrad=2.058000000e+03; //in mm + float plugz=2.650000000e+03; //in mm + + float tmpcos=MainAxis[2]/l; + float tmpsin=sqrt(MainAxis[0]*MainAxis[0]+MainAxis[1]*MainAxis[1])/l; + float detend=0.0; + if(fabs(xStart[2])<2.450000000e+03){ //if in the barrel + detend=(ecalrad-sqrt(xStart[0]*xStart[0]+xStart[1]*xStart[1]))/tmpsin; + }else{ //if in plug + detend=(plugz-fabs(xStart[2]))/fabs(tmpcos); + } + if(detend<0.0) detend=0.0; + + // std::cout << "check length: " << detend << " " + // << xStart[0]/ll << " " << xStart[1]/ll << " " << xStart[2]/ll << " " + // << MainAxis[0]/l << " " << MainAxis[1]/l << " " << MainAxis[1]/l << std::endl; + for (int i(0); i < _nHits; ++i) { xx[0] = _xHit[i] - xStart[0]; xx[1] = _yHit[i] - xStart[1]; xx[2] = _zHit[i] - xStart[2]; float xx2(0.); for (int j(0); j < 3; ++j) xx2 += xx[j]*xx[j]; - + _xl[i] = 0.001 + vecProject(xx,MainAxis); - _xt[i] = sqrt(std::max(0.0,xx2 + 0.1 - _xl[i]*_xl[i])); + _xt[i] = sqrt(std::max(0.0,xx2 + 0.01 - _xl[i]*_xl[i])); // std::cout << i << " " << _xl[i] << " " << _xt[i] << " " << _aHit[i] << " " // << std::endl; } - - for (int i = 0; i < _nHits; ++i) { - _t[i] = _xl[i]/X0; - _s[i] = _xt[i]/Rm; + + //first, check ecal and solve wrong behaviour + //std::cout << "param: " << X0[0] << " " << X0[1] << " " << Rm[0] << " " << Rm[1] << std::endl; + for (int i = 0; i < _nHits; ++i) { + //if(_types[i]==0 || _types[i]==3){ //if the hit is in Ecal + _t[i] = _xl[i]/X0[0]; + _s[i] = _xt[i]/Rm[0]; + if(detend<_xl[i]){ + //std::cout << "something wrong!! " << detend << " " << _xl[i] << " " << _t[i] << std::endl; + //detend = _xl[i]; //to avoid wrong behaviour + } + //} } - + + //second, check hcal + /*for (int i = 0; i < _nHits; ++i) { + if(_types[i]==1 || _types[i]==4){ //if the hit is in Hcal + if(_xl[i]>detend){ + _t[i] = detend/X0[0]+(_xl[i]-detend)/X0[1]; + _s[i] = _xt[i]/Rm[1]; + }else{ + _t[i] = _xl[i]/X0[0]; + _s[i] = _xt[i]/Rm[0]; + } + } + // std::cout << _types[i] << " " << _xl[i] << " " + // << _xl[i]+sqrt(xStart[0]*xStart[0]+xStart[1]*xStart[1]+xStart[2]*xStart[2]) << " " + // << _t[i] << " " << _s[i] << std::endl; + }*/ + _ifNotEigensystem = 0; - + return 0; // no error messages at the moment } @@ -1764,7 +1827,7 @@ float ClusterShapes::calculateChi2Fit3DProfileSimple(float a, float b, float c, // ClusterShapes::transformToEigensystem needs to be executed before float chi2 = 0.0; - float Ampl = 0.0; + float Ampl = 0.0; for (int i(0); i < _nHits; ++i) { // old definition of Ampl and chi2 @@ -1804,11 +1867,11 @@ float ClusterShapes::calculateChi2Fit3DProfileAdvanced(float E0, float a, float // debug /* - std::cout << "OUT : " << Ampl << " " << E0 << " " << a << " " << b << " " - << d << " " << t0 << " " << _t[i] << " " << invG(a) << " " - << pow(b*(_t[i]-t0),a-1) << " " << exp(-b*(_t[i]-t0)) << " " - << exp(-d*_s[i]) - << std::endl; + std::cout << "OUT : " << Ampl << " " << E0 << " " << a << " " << b << " " + << d << " " << t0 << " " << _t[i] << " " << invG(a) << " " + << pow(b*(_t[i]-t0),a-1) << " " << exp(-b*(_t[i]-t0)) << " " + << exp(-d*_s[i]) + << std::endl; */ chi2 += ((Ampl - _aHit[i])*(Ampl - _aHit[i]))/(_aHit[i]*_aHit[i]); @@ -1932,6 +1995,8 @@ int ClusterShapes::fit3DProfileAdvanced(float& chi2, double* par_init, double* p const gsl_multifit_fdfsolver_type* T = gsl_multifit_fdfsolver_lmsder; + //std::cout << T << " " << _nHits << " " << npar << std::endl; + gsl_multifit_fdfsolver* Solver = gsl_multifit_fdfsolver_alloc(T,_nHits,npar); gsl_matrix* covar = gsl_matrix_alloc(npar,npar); // covariance matrix @@ -1951,6 +2016,8 @@ int ClusterShapes::fit3DProfileAdvanced(float& chi2, double* par_init, double* p fitfunct.params = &DataSet; gsl_vector_view pinit = gsl_vector_view_array(par_init,npar); + + //std::cout << Solver << " " << &fitfunct << " " << &pinit.vector << std::endl; gsl_multifit_fdfsolver_set(Solver,&fitfunct,&pinit.vector); gsl_set_error_handler_off(); @@ -1958,9 +2025,9 @@ int ClusterShapes::fit3DProfileAdvanced(float& chi2, double* par_init, double* p // perform fit do { iter++; - std::cout << "Multidimensional Fit Iteration started ... ... "; + //std::cout << "Multidimensional Fit Iteration started ... ... "; status = gsl_multifit_fdfsolver_iterate(Solver); - std::cout << "--- DONE ---" << std::endl; + //std::cout << "--- DONE ---" << std::endl; if (status) break; status = gsl_multifit_test_delta (Solver->dx,Solver->x,abs_error,rel_error); @@ -1974,15 +2041,19 @@ int ClusterShapes::fit3DProfileAdvanced(float& chi2, double* par_init, double* p par[3] = (float)gsl_vector_get(Solver->x,3); std::cout << "Status of multidimensional fit : " << status << " " - << "Iterations : " << iter << std::endl; + << "Iterations : " << iter << std::endl; std::cout << "E0 : " << "FIXED" << "\t" << "A : " << par[0] << "\t" << "B : " - << par[1] << "\t" << "D : " << par[2] << "\t" << "t0 : " << par[3] - << std::endl << std::endl; + << par[1] << "\t" << "D : " << par[2] << "\t" << "t0 : " << par[3] + << std::endl << std::endl; */ } while ( status==GSL_CONTINUE && iter < max_iter); - gsl_multifit_covar (Solver->J,rel_error,covar); + //fg: jacobian has been dropped from gsl_multifit_fdfsolver in gsl 2: + gsl_matrix * J = gsl_matrix_alloc(Solver->fdf->n, Solver->fdf->p); + gsl_multifit_fdfsolver_jac(Solver, J); + gsl_multifit_covar( J, rel_error, covar ); + // gsl_multifit_covar (Solver->J,rel_error,covar); // E0 = (float)gsl_vector_get(Solver->x,0); par[0] = (float)gsl_vector_get(Solver->x,0); // A @@ -2003,3 +2074,222 @@ int ClusterShapes::fit3DProfileAdvanced(float& chi2, double* par_init, double* p //============================================================================= +float ClusterShapes::getEmax(float* xStart, int& index_xStart, float* X0, float* Rm){ + + if (_ifNotEigensystem == 1){ + transformToEigensystem(xStart,index_xStart,X0,Rm); + } + + float E_max=0.0; + //int i_max=0; + for (int i = 0; i < _nHits; ++i) { + if (E_max < _aHit[i]) { + E_max = _aHit[i]; + //i_max = i; + } + } + + return E_max; +} + +float ClusterShapes::getsmax(float* xStart, int& index_xStart, float* X0, float* Rm){ + + if (_ifNotEigensystem == 1){ + transformToEigensystem(xStart,index_xStart,X0,Rm); + } + + float E_max=0.0,xl_max=0.0; + float xl_start=1.0e+50; + //int i_max=0; + for (int i = 0; i < _nHits; ++i) { + //check the position of maximum energy deposit + if (E_max < _aHit[i]) { + E_max = _aHit[i]; + xl_max = _xl[i]; + //i_max = i; + } + //check the position of shower start + if (xl_start > _xl[i]) { + xl_start = _xl[i]; + } + } + + return fabs(xl_max-xl_start); +} + +float ClusterShapes::getxl20(float* xStart, int& index_xStart, float* X0, float* Rm){ + + if (_ifNotEigensystem == 1){ + transformToEigensystem(xStart,index_xStart,X0,Rm); + } + + float *xl_res = new float[_nHits]; + float *E_res = new float[_nHits]; + float E_tot=0.0; + for (int i = 0; i < _nHits; ++i) { + E_res[i]=_aHit[i]; + xl_res[i]=_xl[i]; + + E_tot+=_aHit[i]; + } + + //sort deposite energy to xs ascending order + float tmpe=0.0, tmpxl=0.0; + for (int i = 0; i < _nHits; ++i) { + for (int j = i + 1; j < _nHits; ++j) { + if(xl_res[i]>xl_res[j]){ + tmpe=E_res[i]; + E_res[i]=E_res[j]; + E_res[j]=tmpe; + + tmpxl=xl_res[i]; + xl_res[i]=xl_res[j]; + xl_res[j]=tmpxl; + } + } + } + + // std::cout << "check xt: " << xt_res[0] << " " << xt_res[1] << " " << xt_res[2] + // <<std::endl; + float E20=0.0,okxl=0.0; + int k=0; + while(E20/E_tot<0.2){ + E20+=E_res[k]; + k++; + } + + //final hit is located in outer radius + okxl=xl_res[k-2]; + + delete[] xl_res; + delete[] E_res; + + return okxl; +} + +float ClusterShapes::getxt90(float* xStart, int& index_xStart, float* X0, float* Rm){ + + if (_ifNotEigensystem == 1){ + transformToEigensystem(xStart,index_xStart,X0,Rm); + } + + float *xt_res = new float[_nHits]; + float *E_res = new float[_nHits]; + float E_tot=0.0; + for (int i = 0; i < _nHits; ++i) { + E_res[i]=_aHit[i]; + xt_res[i]=_xt[i]; + + E_tot+=_aHit[i]; + } + + //sort deposite energy to xt ascending order + float tmpe=0.0, tmpxt=0.0; + for (int i = 0; i < _nHits; ++i) { + for (int j = i + 1; j < _nHits; ++j) { + if(xt_res[i]>xt_res[j]){ + tmpe=E_res[i]; + E_res[i]=E_res[j]; + E_res[j]=tmpe; + + tmpxt=xt_res[i]; + xt_res[i]=xt_res[j]; + xt_res[j]=tmpxt; + } + } + } + + // std::cout << "check xt: " << xt_res[0] << " " << xt_res[1] << " " << xt_res[2] + // <<std::endl; + float E90=0.0,okxt=0.0; + int k=0; + while(E90/E_tot<0.9){ + E90+=E_res[k]; + k++; + } + + //final hit is located in outer radius + okxt=xt_res[k-2]; + + delete[] xt_res; + delete[] E_res; + + return okxt; +} + +//for test +void ClusterShapes::gethits(float* xStart, int& index_xStart, float* X0, float* Rm, float *okxl, float *okxt, float *oke){ + + if (_ifNotEigensystem == 1){ + transformToEigensystem(xStart,index_xStart,X0,Rm); + } + + for (int i = 0; i < _nHits; ++i) { + okxl[i]=_xl[i]; + okxt[i]=_xt[i]; + oke[i]=_aHit[i]; + } + + return; +} + + +float ClusterShapes::getRhitMean(float* xStart, int& index_xStart, float* X0, float* Rm){ + + if (_ifNotEigensystem == 1){ + transformToEigensystem(xStart,index_xStart,X0,Rm); + } + + float MainCentre[3]; + + MainCentre[0] = _analogGravity[0]; + MainCentre[1] = _analogGravity[1]; + MainCentre[2] = _analogGravity[2]; + + // float Rhit[_nHits]={0}; + float Rhit=0; + + float Rhitsum=0; + float Rhitmean=0; + + for (int i = 0; i < _nHits; ++i) { + Rhit = sqrt(pow((_xHit[i]-MainCentre[0]),2) + pow((_yHit[i]-MainCentre[1]),2)); + Rhitsum += Rhit; + } + // cogx-- xx[0] + + Rhitmean = Rhitsum/_nHits; + + return Rhitmean; +} + +float ClusterShapes::getRhitRMS(float* xStart, int& index_xStart, float* X0, float* Rm){ + + if (_ifNotEigensystem == 1){ + transformToEigensystem(xStart,index_xStart,X0,Rm); + } + + float MainCentre[3]; + + MainCentre[0] = _analogGravity[0]; + MainCentre[1] = _analogGravity[1]; + MainCentre[2] = _analogGravity[2]; + + // float Rhit[_nHits]={0}; + float Rhit=0; + + float Rhit2sum=0; + float Rhitrms=0; + + for (int i = 0; i < _nHits; ++i) { + Rhit = sqrt(pow((_xHit[i]-MainCentre[0]),2) + pow((_yHit[i]-MainCentre[1]),2)); + Rhit2sum += pow(Rhit,2); + } + // cogx-- xx[0] + + Rhitrms = sqrt(Rhit2sum/_nHits); + + return Rhitrms; +} + +