Changeset 2474 for trunk/MagicSoft/Mars/mmontecarlo
- Timestamp:
- 11/05/03 14:47:52 (21 years ago)
- Location:
- trunk/MagicSoft/Mars/mmontecarlo
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/MagicSoft/Mars/mmontecarlo/MMcWeightEnergySpecCalc.cc
r2448 r2474 25 25 ////////////////////////////////////////////////////////////////////////////// 26 26 // 27 // M WeightEnergySlopeCalc27 // MMcWeightEnergySlopeCalc 28 28 // 29 29 // Change the spectrum of the MC showers simulated with Corsika (a power law) 30 30 // to a new one, which can be either, again a power law but with a different 31 // spectral index, or a generalizeed spectra (given as a TF1 object) 31 // spectral index, or a generalizeed spectrum. The new spectrum can be 32 // pass to this class in different ways: 33 // 1. Is the new spectrum will be a power law, just introduce the slope 34 // of this power law. 35 // 2. Is the new spectrum will have a general shape, different options are 36 // available: 37 // a) The new spectrum is pass as a TF1 function 38 // b) The new spectrum is pass as a char* 39 // c) The new spectrum is pass as a "interpreted function", i.e., a 40 // function defined inside a ROOT macro, which will be invoked by the 41 // ROOT Cint itself. This is the case when we use ROOT macros. 42 // d) The new spectrum is pass as a "real function", i.e., a 43 // function defined inside normal c++ file. 32 44 // 33 45 // Method: 34 46 // ------ 35 47 // 36 // -Corsika spectrun: dN/dE = A * E^( -a)48 // -Corsika spectrun: dN/dE = A * E^(a) 37 49 // with a = fCorsikaSlope, and A = N/integral{E*de} from ELowLim to EUppLim 38 50 // … … 43 55 // a weight to each event, given by: 44 56 // 45 // W(E) = B/A * g(E)/E^(-a) 46 // 47 // (The factor B/A is introduced in order both the original and new spectrum 48 // have the same area (i.e. number of showers)) 57 // W(E) = B/A * g(E)/E^(a) 58 // 59 // In the case the new spectrum is simply a power law: dN/dE = B * E^(b), we 60 // have: 61 // 62 // W(E) = B/A * E^(b-a) 63 // 64 // (The factor B/A is used in order both the original and new spectrum have 65 // the same area (i.e. in order they represent the same number of showers)) 49 66 // 50 67 // Note: 51 68 // ------ 52 // -In the calculations, the new spectrum is treated internally as a TF1 53 // object, to give to the user the option of applying a general spectrum. 54 // Is the new spectrum is just a power law (i.e. the user only specify the 55 // slope),it is converted to a TF1 object for consistency. 56 // -With the original corsika spectrum, as it is always a power law, not TF1 57 // object is used to represent the spectrum. 58 // 59 // 69 // -If the the new spectrum is just a power law (i.e. the user only specify 70 // the slope), the needed calculations (such as the integral of the 71 // spectrum) are done analytically. But if the new spectrum is given as a 72 // TF1 object, the calculations is done numerically. 73 // 74 // ToDo: 75 // ----- 76 // -Give to the user also the possibility to specify the integral of the 77 // spectrum as another TF1 object (or C++ function) 78 // 79 // 60 80 // Input Containers: 61 81 // MMcEvt, MMcRunHeader, MMcCorsikaRunHeader … … 85 105 86 106 107 void MMcWeightEnergySpecCalc::Init(const char *name, const char *title) 108 { 109 110 fName = name ? name : "MMcWeightEnergySpecCalc"; 111 fTitle = title ? title : "Task to calculate weights to change the energy spectrum"; 112 113 AddToBranchList("MMcEvt.fEnergy"); 114 115 fAllEvtsTriggered = kFALSE; 116 fTotalNumSimulatedShowers = 0; 117 } 118 119 87 120 // --------------------------------------------------------------------------- 88 121 // 122 // Constructor. The new spectrum will be just a power law. 89 123 // 90 124 MMcWeightEnergySpecCalc::MMcWeightEnergySpecCalc(Float_t slope, … … 92 126 { 93 127 fNewSpecIsPowLaw = kTRUE; 94 95 128 fNewSlope = slope; 96 129 97 fNewSpectrum = new TF1("NewSpectrum","pow(x,[0])"); 98 fNewSpectrum->SetParameter(0,fNewSlope); 99 100 101 fName = name ? name : "MMcWeightEnergySpecCalc"; 102 fTitle = title ? title : "Task to calculate weights to change the energy spectrum"; 103 104 AddToBranchList("MMcEvt.fEnergy"); 105 106 fAllEvtsTriggered = kFALSE; 107 fTotalNumSimulatedShowers = 0; 108 } 109 110 MMcWeightEnergySpecCalc::MMcWeightEnergySpecCalc(TF1* spectrum, 130 fNewSpectrum = NULL; 131 132 Init(name,title); 133 } 134 135 // 136 // Constructor. The new spectrum will have a general shape, given by the user 137 // as a TF1 function. 138 // 139 MMcWeightEnergySpecCalc::MMcWeightEnergySpecCalc(const TF1& spectrum, 111 140 const char *name, const char *title) 112 141 { 113 142 fNewSpecIsPowLaw = kFALSE; 114 115 fNewSpectrum = spectrum; 116 117 fName = name ? name : "MMcWeightEnergySpecCalc"; 118 fTitle = title ? title : "Task to calculate weights to change the energy spectrum"; 119 120 AddToBranchList("MMcEvt.fEnergy"); 121 122 fAllEvtsTriggered = kFALSE; 123 fTotalNumSimulatedShowers = 0; 124 } 125 126 143 fNewSpectrum = (TF1*)spectrum.Clone(); 144 145 Init(name,title); 146 } 147 148 // 149 // As before, but the function which represent the new spectrum is given as 150 // a char* . Starting from it, we build a TF1 function 151 // 152 MMcWeightEnergySpecCalc::MMcWeightEnergySpecCalc(const char* spectrum, 153 const char *name, const char *title) 154 { 155 fNewSpecIsPowLaw = kFALSE; 156 fNewSpectrum = new TF1("NewSpectrum",spectrum); 157 158 Init(name,title); 159 } 160 161 // 162 // As before, but the new spectrum is given as a intrepreted C++ function. 163 // Starting from it we build a TF1 function. 164 // This constructor is called for interpreted functions by CINT, i.e., when 165 // the functions are declared inside a ROOT macro. 166 // 167 // NOTE: you muss do a casting to (void*) of the function that you pass to this 168 // constructor before invoking it in a macro, e.g. 169 // 170 // Double_t myfunction(Double_t *x, Double_t *par) 171 // { 172 // ... 173 // } 174 // 175 // MMcWeightEnergySpecCalc wcalc((void*)myfunction); 176 // 177 // tasklist.AddToList(&wcalc); 178 // 179 // otherwise ROOT will invoke the constructor McWeightEnergySpecCalc( 180 // const char* spectrum, const char *name, const char *title) 181 // 182 MMcWeightEnergySpecCalc::MMcWeightEnergySpecCalc(void* function, 183 const char *name, const char *title) 184 { 185 fNewSpecIsPowLaw = kFALSE; 186 fNewSpectrum = new TF1("NewSpectrum",function,0,1,1); 187 188 Init(name,title); 189 } 190 191 // 192 // As before, but this is the constructor for real functions, i.e. it is called 193 // when invoked with the normal C++ compiler, i.e. not inside a ROOT macro. 194 // 195 MMcWeightEnergySpecCalc::MMcWeightEnergySpecCalc(Double_t (*function)(Double_t*x, Double_t* par), const Int_t npar, const char *name, const char *title) 196 { 197 fNewSpecIsPowLaw = kFALSE; 198 fNewSpectrum = new TF1("NewSpectrum",function,0,1,1); 199 200 Init(name,title); 201 } 202 203 204 205 // ---------------------------------------------------------------------------- 206 // 207 // Destructor. Deletes the cloned fNewSpectrum. 208 // 127 209 MMcWeightEnergySpecCalc::~MMcWeightEnergySpecCalc() 128 210 { 129 delete fNewSpectrum; 130 } 211 if (fNewSpectrum) 212 delete fNewSpectrum; 213 } 214 131 215 132 216 … … 139 223 fMcEvt = (MMcEvt*)pList->FindObject("MMcEvt"); 140 224 if (!fMcEvt) 141 {142 143 144 }145 146 fWeight = (MWeight*)pList->Find Object("MWeight");225 { 226 *fLog << err << dbginf << "MMcEvt not found... exit." << endl; 227 return kFALSE; 228 } 229 230 fWeight = (MWeight*)pList->FindCreateObj("MWeight"); 147 231 if (!fWeight) 148 { 149 fWeight = (MWeight*)pList->FindCreateObj("MWeight"); 150 if (!fWeight) 151 return kFALSE; 152 } 153 232 { 233 *fLog << err << dbginf << "MWeight not found... exit." << endl; 234 return kFALSE; 235 } 236 154 237 return kTRUE; 155 238 } 156 239 157 240 241 158 242 // ---------------------------------------------------------------------------- 159 243 // 160 244 // Executed each time a new root file is loaded 161 // We will need the fCorsikaSlope,and fE{Upp,Low}Lim to calculate the weights245 // We will need fCorsikaSlope and fE{Upp,Low}Lim to calculate the weights 162 246 // 163 247 Bool_t MMcWeightEnergySpecCalc::ReInit(MParList *plist) … … 178 262 179 263 180 fCorsikaSlope = corrunheader->GetSlopeSpec();181 fELowLim = corrunheader->GetELowLim();182 fEUppLim = corrunheader->GetEUppLim();264 fCorsikaSlope = (Double_t)corrunheader->GetSlopeSpec(); 265 fELowLim = (Double_t)corrunheader->GetELowLim(); 266 fEUppLim = (Double_t)corrunheader->GetEUppLim(); 183 267 184 268 fTotalNumSimulatedShowers += runheader->GetNumSimulatedShowers(); … … 195 279 *fLog << inf << "Only triggered events avail: " << (fAllEvtsTriggered?"yes":"no") << endl; 196 280 197 198 199 // 200 // Starting from fCorsikaSlope, and fE{Upp,Low}Lim, calculate the integrals 281 282 283 // 284 // Sanity checks to be sure that we won't divide by zero later on 285 // 286 if(fCorsikaSlope == -1. || fNewSlope == -1.) 287 { 288 *fLog << err << "The Slope of the power law must be different of -1... exit" << endl; 289 return kFALSE; 290 } 291 292 293 // 294 // Starting from fCorsikaSlope and fE{Upp,Low}Lim, calculate the integrals 201 295 // of both, the original Corsika spectrum and the new one. 202 296 // … … 204 298 // For the Corsika simulated spectrum (just a power law), we have: 205 299 // 206 Double_t a = fCorsikaSlope; 207 fCorSpecInt = ( pow(fEUppLim,1+a) - pow(fELowLim,1+a) ) / ( 1+a ); 300 fCorSpecInt = ( pow(fEUppLim,1+fCorsikaSlope) - pow(fELowLim,1+fCorsikaSlope) ) / ( 1+fCorsikaSlope ); 208 301 302 209 303 // 210 304 // For the new spectrum: 211 305 // 212 fNewSpectrum->SetRange(fELowLim, fEUppLim);213 214 306 if (fNewSpecIsPowLaw) // just the integral of a power law 215 307 { 216 Double_t b = fNewSlope; 217 fNewSpecInt = ( pow(fEUppLim,1+b) - pow(fELowLim,1+b) ) / ( 1+b ); 308 fNewSpecInt = ( pow(fEUppLim,1+fNewSlope) - pow(fELowLim,1+fNewSlope) )/ ( 1+fNewSlope ); 218 309 } 219 310 else 220 { // In this case we have to integrate the new spectrum numerically. We 311 { 312 fNewSpectrum->SetRange(fELowLim, fEUppLim); 313 314 // In this case we have to integrate the new spectrum numerically. We 221 315 // could do simply fNewSpectrum->Integral(fELowLim,fEUppLim), but ROOT 222 316 // fails integrating up to fEUppLim for a sharp cutoff spectrum … … 226 320 // fNewSpectrum->Integral(fELowLim,fEUppLim) (although not perfectlly) 227 321 // 228 fNewSpectrum->SetNpx(1 e4);322 fNewSpectrum->SetNpx(1000); 229 323 TGraph gr(fNewSpectrum,"i"); 230 324 Int_t Npx = gr.GetN(); 231 325 Double_t* y = gr.GetY(); 232 326 233 Double_t integral = y[Npx-1];327 const Double_t integral = y[Npx-1]; 234 328 fNewSpecInt = integral; 235 329 } … … 240 334 241 335 336 242 337 // ---------------------------------------------------------------------------- 243 338 // … … 247 342 const Double_t energy = fMcEvt->GetEnergy(); 248 343 249 Double_t weight = fCorSpecInt/fNewSpecInt * fNewSpectrum->Eval(energy) / pow(energy,fCorsikaSlope); 344 const Double_t C = fCorSpecInt / fNewSpecInt; 345 Double_t weight; 346 347 348 if (fNewSpecIsPowLaw) 349 weight = C * pow(energy,fNewSlope-fCorsikaSlope); 350 else 351 weight = C * fNewSpectrum->Eval(energy) / pow(energy,fCorsikaSlope); 250 352 353 251 354 fWeight->SetWeight( weight ); 252 355 … … 271 374 272 375 376 377 378 -
trunk/MagicSoft/Mars/mmontecarlo/MMcWeightEnergySpecCalc.h
r2448 r2474 7 7 8 8 9 10 9 class MParList; 11 10 class MMcEvt; … … 13 12 class TF1; 14 13 14 15 15 class MMcWeightEnergySpecCalc : public MTask 16 16 { 17 private:18 const MMcEvt *fMcEvt;19 MWeight *fWeight;20 17 21 TF1* fNewSpectrum; // Function with the new spectrum18 private: 22 19 23 Bool_t fNewSpecIsPowLaw; // Tells whether the new spectrum is introduce as24 //a TF1 object or not20 const MMcEvt *fMcEvt; 21 MWeight *fWeight; 25 22 26 UInt_t fTotalNumSimulatedShowers; 27 Bool_t fAllEvtsTriggered; 28 Float_t fCorsikaSlope; // Slope of energy spectrum generated with Corsika 29 Float_t fNewSlope; // Slope of the new spectrum (if it is a power law) 30 Float_t fELowLim; 31 Float_t fEUppLim; // Limits of energy range for generation 32 Double_t fCorSpecInt; // Value of the integrals of the Corsika and new 33 Double_t fNewSpecInt; //spectrum respectively, between fElow and fUppLim 23 TF1* fNewSpectrum; // Function with the new spectrum 34 24 25 Bool_t fNewSpecIsPowLaw; // Tells whether the new spectrum is introduced 26 //as a TF1 object or not 27 Double_t fCorsikaSlope; // Slope of energy spectrum generated with Corsika 28 Double_t fNewSlope; // Slope of the new spectrum (if it is a power law) 29 Double_t fELowLim; 30 Double_t fEUppLim; // Limits of energy range for generation 31 Double_t fCorSpecInt; // Value of the integrals of the Corsika and new 32 Double_t fNewSpecInt; //spectrum respectively, between fElow and fUppLim 35 33 34 UInt_t fTotalNumSimulatedShowers; 35 Bool_t fAllEvtsTriggered; 36 36 37 void Init(const char *name, const char *title); 37 38 Bool_t ReInit(MParList *plist); 38 39 … … 41 42 42 43 43 public: 44 public: 45 44 46 MMcWeightEnergySpecCalc(const Float_t slope, 45 47 const char *name=NULL, const char *title=NULL); 46 48 47 MMcWeightEnergySpecCalc(TF1* spectrum, 48 const char *name=NULL, const char *title=NULL); 49 MMcWeightEnergySpecCalc(const TF1& spectrum, 50 const char *name=NULL, const char *title=NULL); 51 52 MMcWeightEnergySpecCalc(const char* spectrum, 53 const char *name=NULL, const char *title=NULL); 54 55 MMcWeightEnergySpecCalc(void *function, 56 const char *name=NULL, const char *title=NULL); 57 58 MMcWeightEnergySpecCalc(Double_t (*function)(Double_t* x, Double_t* par), 59 const Int_t npar, const char *name=NULL, const char *title=NULL); 60 49 61 50 62 ~MMcWeightEnergySpecCalc(); 63 51 64 52 65 ClassDef(MMcWeightEnergySpecCalc, 0) // Task to convert the spectrum of the MC showers simulated with Corsika to a different one, by using weights
Note:
See TracChangeset
for help on using the changeset viewer.